/*
区间覆盖问题,一次AC
题意:使用题中所给坐标[Li,Ri]覆盖[0,M],如果不能覆盖输出0,如果可以,输出使用最少坐标的情况,并输出其序列,要求按Li进行排序。
思路:其中刘汝佳书中有这道题的详细思路,但是我感觉实现起来蛮复杂,所以使用自己的思路进行解答。
首先按Li对坐标进行排序,找出其中Li<=l的情况,选择其中Ri最大的那个坐标,判断是否满足Ri>l如果满足,则转变为对[Ri,M]的覆盖,如果不满足则结束。贪心思路即:按Li进行排序,寻找其中Ri最大的那种情况。
*/
#include <cstdio>
#include <cstdlib>
const int nMax=100007;
struct Node
{
int Li;
int Ri;
Node(int Li,int Ri):Li(Li),Ri(Ri){}
Node(){}
}A[nMax];
int n;
int ans[nMax],m;
bool ok;
int cmp(const void *a,const void *b)
{
Node *pa=(Node *)a;
Node *pb=(Node *)b;
return pa->Li-pb->Li;
}
void cover(int l,int r,int cur)
{
if(l >= r)
{
ok=1;
return;
}
int i;
for(i = cur; i < n; i++)
if(A[i].Li > l)
break;
int j;
int max=cur;
for(j = cur + 1; j < i; j++)
if(A[j].Ri > A[max].Ri)
max=j;
if(A[max].Ri > l)
{
ans[m++]=max;
cover(A[max].Ri,r,i);
}
else
return;
}
int main()
{
//freopen("f://data.in","r",stdin);
int T,M;
scanf("%d",&T);
while(T--)
{
ok=false;
m=0;n=0;
scanf("%d",&M);
int a,b;
while(scanf("%d %d",&a,&b)!=EOF)
{
if(a==0 && b==0) break;
A[n]=Node(a,b);
n++;
}
qsort(A,n,sizeof(A[0]),cmp);
cover(0,M,0);
if(ok)
{
printf("%d\n",m);
for(int i=0;i<m;i++)
printf("%d %d\n",A[ans[i]].Li,A[ans[i]].Ri);
}
else
printf("0\n");
if(T) printf("\n");
}
return 0;
}
10020 - Minimal coverage
最新推荐文章于 2019-07-02 13:31:00 发布