UVA-10020 Minimal coverage(贪心)
题目大意:在x轴上,给一些区间,求出能把[0,m]完全覆盖的最少区间个数及该情形下的各个区间。
题目分析:简单的区间覆盖问题。可以按这样一种策略进行下去:在所有区间起点、长度有序的前提下,对于当前起点,找到可以覆盖下去的最长区间进行覆盖,并不断更新起点,直到覆盖完所有区间。
代码如下:
# include<iostream> # include<cstdio> # include<vector> # include<cstring> # include<algorithm> using namespace std; struct QuJian { int l,r; QuJian(){} QuJian(int _l,int _r):l(_l),r(_r){} bool operator < (const QuJian &a) const {///先按起点位置,再按区间长短排序 if(l==a.l) return r>a.r; return l<a.l; } }; vector<QuJian>P,q; void init() {///扔掉无意义的区间(属于其他区间的区间) sort(q.begin(),q.end()); vector<QuJian>::iterator it,it1; for(it=q.begin();it!=q.end();++it){ it1=(++it),--it; while(it1!=q.end()){ if(it1->l>=it->l&&it1->r<=it->r) q.erase(it1); else break; } } } void solve(int &r,const int &m) { int len=q.size(); for(int i=0;i<len&&r<m;++i){///漏写“r<m”,导致WA了一上午。。。 if(q[i].l>r)///无法进行下去,覆盖失败 break; if(i+1<len&&q[i+1].l<=r&&q[i+1].r>=q[i].r)///在区间可以覆盖的前提下,寻找长度最长的区间 continue; r=q[i].r; P.push_back(q[i]); } } void print(int &r,const int &m) { if(r<m) printf("0\n"); else{ printf("%d\n",P.size()); for(int i=0;i<P.size();++i) printf("%d %d\n",P[i].l,P[i].r); } } int main() { //freopen("UVA-10020 Minimal coverage.txt","r",stdin); int T,m,a,b; scanf("%d",&T); while(T--) { q.clear(); P.clear(); scanf("%d",&m); while(scanf("%d%d",&a,&b)&&(a+b)) {///选择有价值的区间 if(a>b) swap(a,b); if(a>m||b<0) continue; q.push_back(QuJian(a,b)); } init(); int r=0; solve(r,m); print(r,m); if(T) printf("\n"); } return 0; }