闭区间合并
- 总时间限制:
- 1000ms
- 内存限制:
- 65536kB
- 描述
-
给定 n 个闭区间 [ai; bi],其中i=1,2,...,n。任意两个相邻或相交的闭区间可以合并为一个闭区间。例如,[1;2] 和 [2;3] 可以合并为 [1;3],[1;3] 和 [2;4] 可以合并为 [1;4],但是[1;2] 和 [3;4] 不可以合并。
我们的任务是判断这些区间是否可以最终合并为一个闭区间,如果可以,将这个闭区间输出,否则输出no。
- 输入
- 第一行为一个整数n,3 ≤ n ≤ 50000。表示输入区间的数量。
之后n行,在第i行上(1 ≤ i ≤ n),为两个整数 ai 和 bi ,整数之间用一个空格分隔,表示区间 [ai; bi](其中 1 ≤ ai ≤ bi ≤ 10000)。 - 输出
- 输出一行,如果这些区间最终可以合并为一个闭区间,输出这个闭区间的左右边界,用单个空格隔开;否则输出 no。
- 样例输入
-
5 5 6 1 5 10 10 6 9 8 10
- 样例输出
-
1 10
思路:
刚开始暴力,不行,有多种情况,单边排序还需要双重循环来照顾,果然超时。
然后想到上个火车进站的区间覆盖思路去做,合并成一张表排序,然后找规律
上次那个火车进站是求一个Max,即为相交的最大区间数。加上模拟,进一个出一个。这个合并情况不一样。
只需要判断当sum=0的情况下右边已经不存在l了即可。即遇l加1,遇r减1,不能存在独立的区间
eg:
3
1 2
1 3
4 5
合并排序之后:
1 1 2 3 4 5
l l r r l r
最后一个l出现是sum=0,这种情况就不行的
而
3
1 9
3 4
5 6
合并后
1 3 4 5 6 9
l l r l r r
这种明显就可以。#include <bits/stdc++.h> using namespace std; const int maxn = 50000*2+10; struct Node { int x; char s; } node[maxn]; int cmp(Node a,Node b) { if(a.x != b.x) { return a.x < b.x; } else { return a.s < b.s; } } int main() { // freopen("in.txt","r",stdin); int n; while(~scanf("%d",&n)){ for(int i = 0; i < n*2; i++) { scanf("%d",&node[i].x); if((i+1)%2==1) node[i].s = 'l'; else { node[i].s = 'r'; } } sort(node,node+n*2,cmp); int flag = 0; int sum = 1;//默认跳过第一个左区间即可 for(int i = 1; i < n*2; i++) { if(node[i].s == 'l') { if(sum == 0) { flag = 1; } sum++; } else sum--; } if(flag == 1) { puts("no"); } else { printf("%d %d\n",node[0].x,node[n*2-1].x); } } return 0; }