题目描述
给定 n 个区间 [li, ri],要求合并所有有交集的区间。注意如果在端点处相交,也算有交集。
输出合并完成后的区间个数。
例如:[1, 3] 和 [2, 6] 可以合并为一个区间 [1, 6]。
输入格式
第一行包含整数 n 。
接下来 n 行,每行包含两个整数 l 和 r。第 i 行的两个数据表示 li, ri。
输出格式
共一行,包含一个整数,表示合并区间完成后的区间个数。
数据范围
1≤n≤100,000
−10^9≤li≤ri≤10^9
输入样例
5
1 2
2 4
5 6
7 8
7 9
输出样例
3
注释版代码
//http://47.110.135.197/problem.php?id=5240
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
typedef pair<int,int> PII;
vector<PII> segs;
vector<PII> res;//res用于存放合并完的区间
void merge(vector<PII> &segs)
{
sort(segs.begin(),segs.end());//先对区间进行排序,pair排序是按照左断点先排序,再按照右端点排序
int st=-2e9,ed=-2e9;//将st和ed定义为极限小,因为题目的数据范围是10^9,所以定义极限小可以定义2e9
for(auto seg:segs)
{
//对于两区间之间的关系有两种情况
//①前面区间与后面区间没有交集:那么没有交集就说明前面区间已经不能与后面区间合并
//那么前面的区间就已经不能再合并了,可以放入结果集了
if(ed<seg.first)//这样定义ed=-2e9就可以保证第一个有效区间能进行操作
{
if(st!=-2e9)//只要他不是我们取的无限小,就可以放入结果集了
{
res.push_back({st,ed});
}
st=seg.first,ed=seg.second;//然后更新st为后面区间的l和r
}
//②前面区间与后面区间有交集:那么我们只需要把ed更新为前面区间和后面区间相比较大的右端点就可以了
else ed=max(ed,seg.second);
}
if(st!=-2e9) res.push_back({st,ed});//如果只有一个区间,我们就需要用到这个步骤
}
int main()
{
int n,l,r;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d %d",&l,&r);
segs.push_back({l,r});//将每一个lr代表的区间存入segs里面
}
merge(segs);//对segs区间进行合并操作
printf("%d",res.size());//输出合并完的区间个数
return 0;
}