思路:
1. 按区间左端点排序
2. 扫描整个区间,扫描过程中将所有有交集的区间合并,第i个区间与当前维护的区间的关系分三种情况:
- 第i个区间在当前区间的内部,区间合并完以后左右端点st,ed不变
- 第i个区间与当前区间有交集,但不在内部,区间合并完以后ed_cur=ed_new,区间延长
- 第i个区间与当前区间没有交集,将当前维护的区间返回,更新维护的区间为第i个区间
具体实现代码
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
typedef pair<int,int>PII;
int n;
vector<PII> segs;
void merge(vector<PII> &segs)
{
vector<PII> res;
sort(segs.begin(),segs.end());
int st = -2e9,ed = -2e9; //初始化区间左右端点
for(auto seg : segs)
if(ed < seg.first) //如果没有交集
{
if(st != -2e9) res.push_back({st,ed}); //区间不为空,则保存结果
st = seg.first,ed = seg.second; //然后更新当前维护的区间
}
else ed = max(ed,seg.second); //有交集,则更新右端点为最大值
if(st != -2e9) res.push_back({st,ed}); //判断区间是否为空
segs = res;
}
int main()
{
cin>>n;
for(int i=0;i<n;i++)
{
int l,r;
cin>>l>>r;
segs.push_back({l,r});
}
merge(segs);
cout<<segs.size()<<endl;
return 0;
}
题目来了
校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米。我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置;数轴上的每个整数点,即0,1,2,……,L,都种有一棵树。
由于马路上有一些区域要用来建地铁。这些区域用它们在数轴上的起始点和终止点表示。已知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分。现在要把这些区域中的树(包括区域端点处的两棵树)移走。你的任务是计算将这些树都移走后,马路上还有多少棵树。
输入描述:
第一行有两个整数:L(1 <= L <= 10000)和 M(1 <= M <= 100),L代表马路的长度,M代表区域的数目,L和M之间用一个空格隔开。接下来的M行每行包含两个不同的整数,用一个空格隔开,表示一个区域的起始点和终止点的坐标。
输出描述:
包括一行,这一行只包含一个整数,表示马路上剩余的树的数目。
输入
500 3
150 300
100 200
470 471
输出
298
备注:
对于20%的数据,区域之间没有重合的部分;
对于其它的数据,区域之间有重合的情况。
棒啊!不过加一个题目描述更好.