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;
}

  

posted @ 2015-08-28 12:39  20143605  阅读(156)  评论(0编辑  收藏  举报