1、最小区间覆盖问题,比较经典,用贪心法解决。
2、要注意的是刚开始要判断有没有left<=0且right>0的区间,有再进行搜索,否则会RE。
3、搜索到right>=M的区间后立即停止,否则区间数量就不是最小。
#include<cstdio>
#include<algorithm>
using namespace std;
struct interval{
int l,r;
bool operator <(const interval &obj)const{
return l<obj.l;
}
}a[100010];
int b[100010];
int main(){
int T,M;
scanf("%d",&T);
while(T--){
scanf("%d",&M);
int cnt=0,num=0;
bool flag=false;
while(scanf("%d%d",&a[cnt].l,&a[cnt].r)==2){
if(a[cnt].l==0&&a[cnt].r==0) break;
else cnt++;
}
sort(a,a+cnt);
for(int i=0;i<cnt;i++){
if(a[i].l<=0&&a[i].r>0){
flag=true;break;
}
}
int left=0,max=0,maxi,p=0;
if(!flag){
printf("0\n");
if(T>0)
printf("\n");
continue;
}
else{
int i=p;
while(i<cnt){
for(i=p;i<cnt;i++){
if(a[i].l<=left){
if(a[i].r-left>max){
max=a[i].r-left;
maxi=i;
}
}
else{
p=i;break;
}
}
left=a[maxi].r;max=0;b[num++]=maxi;
if(a[maxi].r>=M) break;
}
}
if(a[b[num-1]].r<M){
printf("0\n");
if(T>0) printf("\n");
continue;
}
printf("%d\n",num);
for(int i=0;i<num;i++)
printf("%d %d\n",a[b[i]].l,a[b[i]].r);
if(T>0) printf("\n");
}
return 0;
}