给定 n 个区间 [li,ri],要求合并所有有交集的区间。
注意如果在端点处相交,也算有交集。
输出合并完成后的区间个数。
例如:[1,3]和 [2,6] 可以合并为一个区间 [1,6]。
输入格式
第一行包含整数 n。
接下来 n 行,每行包含两个整数 l 和 r。
输出格式
共一行,包含一个整数,表示合并区间完成后的区间个数。
数据范围
1≤n≤100000
−109≤li≤ri≤109
输入样例:
5
1 2
2 4
5 6
7 8
7 9
输出样例:
3
代码:
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
const int N = 100010;
typedef pair<int, int> PII;// 定义一对int类型
vector<PII> segs;// 将这对类型储存进入 vector 当中,并将这个类型声明为 segs
void merge(vector<PII>& segs)
{
vector<PII> res;// 重新定义一个名为 res的 vecotr 用来记录进行合并之后的区间
sort(segs.begin(), segs.end());// 将每个区间先按照左端点进行排序
int st = -2e9, ed = -2e9;//ed代表区间结尾,st代表区间开头
for (auto seg : segs)
{
//1.两个区间无法合并
if (ed < seg.first)//如果 进行比较的区间 的左端点 大于 被比较的 区间右端点
{
if (st != -2e9) res.push_back({ st, ed }); //那么只要这个区间不是负无穷小,就将这个区间加入res当中
st = seg.first, ed = seg.second;//进行调整,将这个比较区间 换成 被比较的区间 进行对它之后的区间进行比较
}
//情况2:两个区间可以合并;
else ed = max(ed, seg.second);//如果 进行比较的区间 的左端点 小于等于 被比较的 区间的右端点
} //那么 就将被比较区间的结尾取 它们两之间 的最大值
if (st != -2e9) res.push_back({ st,ed });// 最后 所有的区间比较完成之后,最后剩下的这个比较区间
// 只要 它的左端点不是负无穷小的话 就将它加入 res当中
//因为这是最后的一个序列,所以不可能继续进行合并。
segs = res; //最后将 segs改变成res
}
int main()
{
int n;
cin >> n;
for (int i = 0; i < n; i++)
{
int l, r;
cin >> l >> r;//依次读入区间的左右端点
segs.push_back({ l,r });//将区间的左右端点储存在 segs 当中
}
merge(segs);//调用合并区间的函数
/* for(auto r:segs) printf("%d %d\n",r.first,r.second) ;
puts("") ;*/
//(把上面的注释去掉,可以在调试时用)
cout << segs.size()<<endl;// 输出这个vector 当中的数据个数(区间合并之后的 int类型的对数)
return 0;
}