题意:给你N条线段(Li,Ri)映射到x轴上,然后让你用其中的几条线段(条数最少)覆盖【0,M】
方法:利用贪心思想。对线段按照长度进行排序,在这里可以在输入的时候,对线段进行选择,如果Ri<0||Li>M这直接删除。然后每次在选择线段的时候,尽可能的选择长的,这里用到了贪心思想
#include<iostream> #include<algorithm> #include<cstdio> #include<string.h> using namespace std; int M; struct node { int x1,x2; } Node[100100],an[100100]; int cmp(node a,node b) { return a.x1<b.x1; } int main() { int T; int M; int a,b; int ans=0; scanf("%d",&T); int m=T; while(T--) { ans=0; memset(Node,0,sizeof(Node)); memset(an,0,sizeof(an)); scanf("%d",&M); for(int i=0;; i++) { scanf("%d%d",&a,&b); if(a==0&&b==0) break; if(a>M||b<0) continue; Node[ans].x1=a; Node[ans].x2=b; ++ans; } if(ans==0) { printf("0\n"); } else { int min=0,max=0; int step=0,pox; int f=0; sort(Node,Node+ans,cmp); while(1) { if(min>=M) break; max=0; f=0; for(int i=0; i<ans; i++)//贪心算法 只看左边的数据就行了 { if(min>=Node[i].x1&&max<Node[i].x2)//左边的值一定大于Node[i].x1才能完成覆盖,右边的值一定小与Node[i].x2才能是有效值 { pox=i; f=1; max=Node[i].x2; } } if(f) { an[step++]=Node[pox]; min=Node[pox].x2;//对左边贪心 } else break; } if(f) { printf("%d\n",step); for(int i=0; i<step; i++) printf("%d %d\n",an[i].x1,an[i].x2); } else printf("0\n"); } if(T>0) printf("\n"); } return 0; }