Ural 1303 Minimal Coverage(贪心)
题目地址:Ural 1303
先按每一个线段的左端点排序,然后设置一个起点s。每次都从起点小于等于s的线段中找到一个右端点最大的。
并将该右端点作为新的起点s,然后继续找。
从左到右扫描一遍就可以。
代码例如以下:
#include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #include <math.h> #include <ctype.h> #include <queue> #include <map> #include <set> #include <algorithm> using namespace std; #define LL __int64 const int INF=0x3f3f3f3f; int a[100000]; struct node { int l, r, ll, rr; } fei[100000]; int cmp(node x, node y) { return x.l<y.l; } int main() { int m, i, j, n, l, r, s, max1, cnt=0, tot, pos, flag, flag1, ll, rr; scanf("%d",&m); while(scanf("%d%d",&ll, &rr)!=EOF&&(ll||rr)) { if(rr<=0||ll>=m) continue ; fei[cnt].ll=ll; fei[cnt].rr=rr; l=ll;r=rr; if(l<0) l=0; if(r>m) r=m; fei[cnt].l=l; fei[cnt++].r=r; } sort(fei,fei+cnt,cmp); s=0; tot=0; if(cnt==0) { printf("No solution\n"); } else { for(i=0; i<cnt;) { max1=-1; flag=0; while(fei[i].l<=s&&i<cnt) { flag=1; if(max1<fei[i].r) { max1=fei[i].r; pos=i; } i++; } if(!flag) break; if(s<max1) { a[tot++]=pos; s=max1; } } if(i<cnt||s<m) puts("No solution"); else { printf("%d\n",tot); for(i=0; i<tot; i++) { printf("%d %d\n",fei[a[i]].ll,fei[a[i]].rr); } } } return 0; }