十三.区间合并
比如说有两个区间,如果他们有交集(端点相同也算),则将两个区间合并为一个区间
输入n个区间,将这n个区间中所有有交集的区间进行合并,并输出合并后的区间个数
1.按照左端点从小到大的顺序“扫描”所有区间
2.先选定当前所扫描到的第一个区间为维护区间,设该区间为A左端点st,右端点ed。当扫描到第二个区间时,设为B。B相对A有三种情况
①B的左端点和右端点都比A的小。则A包含B,两者合并
②B的左端点比A小,右端点比A大,则A跟B取为并集
以上两种情况,A和B合并后统一为当前维护区间,称为A
③B的左端点比A的右端点大,则说明B与A没有重合部分。注意因为所有区间扫描顺序都是按照左端点区间从小到大排的,这意味着B之后的所有区间更不可能与A有交集,所以对A的维护结束,把B设为新的维护区间,A
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
typedef pair<int,int> PII;//用来存一个区间的左右端点的
const int N=1---1-;
int n;
vector<PII> segs;
void merge(vector<PII> &segs){
vector<PII> res;
sort(segs.begin(),segs.end());//排序所有区间,pair在c++里面优先以左端点进行排序
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({std,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;
}