题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=85904#problem/D
题意:
数轴上有n个闭区间[Li,Ri],选择尽量少的区间覆盖一条指纹线段[0,M]。
案例:
input
2
1
-1 0
-5 -3
2 5
0 0
1
-1 0
0 1
0 0
output
0
1
0 1
思路分析:
线段区间的起点是0,那么找出所有区间起点小于0中的最合适的区间。
因为需要尽量少的区间,所以选择右端点更大的区间,它包含所选线段更大。
如果在所有区间中找到了解,且右端点小于M,则把找到的区间的右端点定为新的线段区间的起点。
源代码如下:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 int b[2][100010],a[2][100010],t,j,M,s; //一定要看清数组范围 6 void search(int l) 7 { 8 for(int i=0;i<t;i++) 9 if(a[0][i]<=l&&a[1][i]>l&&a[1][i]>b[1][j]) //找到可行区间右端点最大的区间 10 { 11 b[1][j]=a[1][i]; 12 b[0][j]=a[0][i]; 13 } 14 if(b[1][j]!=0&&b[1][j]<M) //注意不要忘了无解的情况 15 { 16 j++; 17 search(b[1][j-1]); //可行区间右端点为新的起点 18 } 19 } 20 int main() 21 { 22 int T; 23 scanf("%d",&T); 24 while(T--) 25 { 26 s=0; 27 j=0; 28 t=0; 29 memset(b,0,sizeof(b)); 30 scanf("%d",&M); 31 scanf("%d%d",&a[0][0],&a[1][0]); 32 while(a[0][t]||a[1][t]) 33 { 34 t++; 35 scanf("%d%d",&a[0][t],&a[1][t]); 36 } 37 search(0); 38 if(!b[1][0]||b[1][j]<M) printf("0\n"); 39 else 40 { 41 printf("%d\n",j+1); //记录的是最后可行解的位置,一定要加1 42 for(int i=0;i<=j;i++) 43 printf("%d %d\n",b[0][i],b[1][i]); 44 } 45 } 46 return 0; 47 }