区间并集
描述:
存在 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;
}
}
}