题意:选择最少的区间覆盖一条线段,如果不能覆盖,则输出0
思路:将区间按左端点从小到大,然后右端点从大到小排序,这样每次覆盖保证能够使得使用的区间尽可能的少,注意覆盖完之后更新线段的左右端点值
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int l;
int r;
} co;
int cmp(const void *_x,const void *_y)
{
co *x=(co *)_x;
co *y=(co *)_y;
if(x->l==y->l)return -x->r+y->r;
return x->l-y->l;
}
int main()
{
co p[100005],ans[100005];
int T,m;
scanf("%d",&T);
while(T--)
{
scanf("%d",&m);
int t=0;
while(scanf("%d%d",&p[t].l,&p[t].r)==2)
{
if(!p[t].l && !p[t].r)break;
++t;
}
qsort(p,t,sizeof(p[0]),cmp);
int L=0,f=0;
int count=0,cl=0,cr=0;
for(int i=0; i<t; i++)
{
if(!i && p[i].l>0)
{
f=1;
break;
}
if(p[i].r>cr)
{
cl=p[i].l;
cr=p[i].r;
}
if(i+1<t&&p[i+1].l>L)
{
L=cr;
ans[count].l=cl;
ans[count].r=cr;
count++;
if(cr>=m)break;
if(p[i+1].l>cr)
{
f=1;
break;
}
}
if(i==t-1)
{
if(count-1<0||cr>ans[count-1].r)
{
ans[count].l=cl;
ans[count].r=cr;
count++;
}
}
}
if(cr<m)f=1;
if(!f)
{
printf("%d\n",count);
for(int i=0; i<count; i++)
printf("%d %d\n",ans[i].l,ans[i].r);
}
else
printf("0\n");
if(T)printf("\n");
}
return 0;
}