RE了两次,又WA了一次,思路题永远都想不明白呀,这个题是lrj书上的区间覆盖问题,因为区间数量最少,所以无所谓这些解区间之间互相覆盖多少,首先那些在[0,m]外的区间没用,不用保存;可以预处理一下这些区间,做断点小于0的可以暂记为0,又区间比m大的,可以暂记为m;然后找区间是关键,每次都要找的区间在满足左端点<=起点的情况下右端点最大,这样既可以覆盖,又优先选择了大区域。节省了区间数量。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
using namespace std;
typedef struct Point
{
int x,y;
int xx,yy;
} Point;
Point p[100001];
int cmp(const void*_a,const void *_b)
{
Point *a=(Point *)_a;
Point *b=(Point *)_b;
if(a->xx-b->xx)
return a->xx-b->xx;
else return a->yy-b->yy;
}
int main()
{
//freopen("in.txt","r",stdin);
int cas,m,n;
scanf("%d",&cas);
while(cas--)
{
scanf("%d",&m);
n=0;
while(scanf("%d%d",&p[n].x,&p[n].y)!=EOF&&(p[n].x||p[n].y))
{
if(p[n].x>=m||p[n].y<=0) ;
else
{
p[n].xx=p[n].x<=0?0:p[n].x;
p[n].yy=p[n].y<=m?p[n].y:m;
n++;
}
}
qsort(p,n,sizeof(p[0]),cmp);
if(p[0].xx>0||n==0)
{
cout<<0<<endl;
if(cas)
cout<<endl;
continue;
}
int begin=0;
int num=0;
int step[10020];
int temp;
while(1)
{
int max=0;
temp=-1;
for(int i=0; i<n; i++)
{
if(p[i].xx<=begin)
{
if(p[i].yy>=max)
{
temp=i;
max=p[i].yy;
}
}
}
step[num++]=temp;
begin=p[temp].yy;
if(begin==m)
break;
if(temp==-1)
break;
}
if(begin!=m)
cout<<0<<endl;
else
{
cout<<num<<endl;
for(int i=0; i<num; i++)
cout<<p[ step[i]].x<<" "<<p[step[i]].y<<endl;
}
if(cas)
cout<<endl;
}
return 0;
}