JGOJ P1512:区间并集

区间并集

描述:
存在 n 个区间:a1、a2、…… 、an。

求 a1 ∪ a2 ∪ a3 ∪ …… ∪ an。

输入:
只有一组案例。

第一行正整数 n 表示区间的个数。(1 <= n <= 1e5)

然后是 n 行,每行包含两个正整数 L 和 R,分别表示一个区间左右端点,即 [ L,R ]。(0 <= L <= R <= 1e10)

输出:
根据左端点的大小,从小到大输出取并集后的每个区间。

每个区间的左端点和右端点之间用空格隔开,每次输出以后都要换行。

样例输入:
6

1 2

1 4

8 10

8 9

5 6

6 7

样例输出:
1 4

5 7

8 10

HINT:
[1,2] 区间和 [1,4] 区间取并集后变为 [1,4]

[5,6] 区间和 [6,7] 区间取并集后变为 [5,7]

[8,9] 区间和 [8,10] 区间取并集后变为 [8,10]

分析
先排序,按左端点的大小进行排序,小的在前,如果左端点相同就比较右端点(要用快排不然可能会超时)。 如果后一个的左端点小于等于前一个的右端点,两个区间就能合并,左端点取最小,右端点取最大,前面的左右端点都要标记(表示和后一个的区间合并在一起了)。


#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
struct point//结构体
{
    
    
	ll l;
	ll r;
}a[100000];
bool cmp(point x, point y)//快排
{
    
    
	if (x.l == y.l)return x.r < y.r;
	else return x.l < y.l;
}
int main()
{
    
    
	int n;
	cin >> n;
	for (int i = 0; i < n; i++)
	{
    
    
		cin >> a[i].l >> a[i].r;
	}
	sort(a, a + n, cmp);//快排
	for (int i = 1; i < n; i++)
	{
    
    
		if (a[i].l <= a[i - 1].r)
		{
    
    
			a[i].l = min(a[i - 1].l, a[i].l);
			a[i].r = max(a[i - 1].r, a[i].r);
			a[i - 1].l = -1;//标记
			a[i - 1].r = -1;
		}
	}
	for (int i = 0; i < n; i++)
	{
    
    
		if (a[i].l != -1 && a[i].r != -1)
		{
    
    
			cout << a[i].l <<" "<< a[i].r << endl;
		}
	}
}

猜你喜欢

转载自blog.csdn.net/YYDS777/article/details/114488781