区间合并---模板题

区间合并

题目链接:https://www.acwing.com/problem/content/805/

给定 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

思路

区间的存储方式:以[左端点,右端点]的形式装进一个vector
1.将vector里面的区间按右端点从小到大排序
2.把vector第一个区间作为当前的区间[l,r],然后遍历vector之后的区间[l2,r2],合并好的区间放进vector res
----------2.1 若l2>r,则将[l,r]装进res,然后当前区间变成[l2,r2]
----------2.2 否则,r变成r2,对区间进行合并,也就是当前区间变成了[l,r2]
3.res的元素为合并好的区间,res的大小就是区间的个数

#include 
using namespace std;

int n;

struct node{
	int l,r;
	friend bool operator < (node a,node b){
		return a.r>b.r; //区间的排序顺序,>表示从小到大。<表示从大到小,和一般的自定义排序相反
	}
};
vector<node> ve;

vector<node> merge(){ //区间合并,把合并好的区间装进vector并返回
	sort(ve.begin(),ve.end());
	vector<node> resv;
	int l = ve[0].l,r = ve[0].r;
	for(int i = 1;i<ve.size();i++){
		if(ve[i].l > r){ //不能将下一个区间用于扩展
			resv.push_back({l,r});
			l = ve[i].l;
			r = ve[i].r;
		}else{//进行扩展
			r = ve[i].r;
		}
	}
	resv.push_back({l,r});
	return resv;
}


int main(){
	cin>>n;
	int l,r;
	while(n--){
		scanf("%d%d",&l,&r);
		ve.push_back({l,r});
	}
	vector<node> res = merge();
	cout<<res.size()<<endl;//vector元素个数即为合并好的区间个数
	
	
	return 0;
}

你可能感兴趣的:(算法暑期集训)