题目描述
输入描述
输出描述
输入样例
2
3 1
2 2
4 2
1 1
3 3
输出样例
1
2 2
2
3 1
1 3
题目大意:输入 m 个保证不重叠的区间,要求你输出 k 个区间,使得 k 个区间的交集与 m 个区间的并集相同。( k 的个数无要求 )
本题由于给的是环形数组,因此可考虑将数字由 1 ~ n 按类时钟方法排列为一圈,而所给的区间即为由 l 按顺时针方向到 r 所覆盖的区间。
不难发现,在该环形数组中,不属于 m 个区间的并集 的集合的个数即为 k 的最小值,而 k 个集合由 m 中每一个集合的 l 到下一个(顺时针)集合的 r 组成,解释图如下
其中,输入的 m 为( 10 , 1 )( 3 , 3 )( 4 , 5 )( 7 , 7 )
取并集后得( 10 , 1 )( 3 , 5 )( 7 , 7 )
由之前得出的结论,k 的最小个数为 3 ,且 k 个集合是由 m 取并集后每个集合的 l 与下一个集合的 r 组合而成,即:
( 10 , 5 )( 3 , 7 )( 7 , 1 )
但对于该样例中比较特殊的( 3 , 3 )( 4 , 5 ),取并集时需要对这两个集合进行判断是否相邻并进行修改,将增加操作次数。而由于 k 的个数没有要求,因此可以考虑将 k 放宽为 m 的个数,将 m 个区间进行排序后按规律直接输出即可。
即( 10 , 3 )( 3 , 5 )( 4 , 7 )( 7 , 1 )
参考代码
#include <bits/stdc++.h>
using namespace std;
const int N =1e4;
struct node{
int l;int r;
}a[N];
bool cmp(node x,node y){
return x.l <y.l ;
}
int main() {
int t;
cin>>t;
while(t--){
int n,m;
cin>>n>>m;
int l,r;
for(int i=0;i<m;i++){
cin>>a[i].l >>a[i].r ;
}
sort(a,a+m,cmp);
cout<<m<<endl;
cout<<a[0].l<<' '<<a[m-1].r<<endl;
for(int i=1;i<m;i++){
cout<<a[i].l<<" "<<a[i-1].r<<endl;
}
}
return 0;
}