uva10020 贪心

题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=961

题目大意:给你一个0~m的区间,然后给你若干线段,问你最少取多少线段可以将0~m完全覆盖

思路分析:贪心思想,(我不贪心所以没做出来),首先给出的线段有一些是没有用的,可以在输入的时候就将这些线段略去,

然后可以按照线段右端点从大到小排序,开始枚举更新右端点,初始时右端点为0(左右端点重合),然后开始枚举这些线段,寻找一条

能够覆盖原有右端点同时能够最大限度更新右端点的线段,并标记这条线段为已用,更新右端点,如果找不到满足的纠结束,最后看右端点是否>m

即可

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=100000+100;
struct node
{
    int l;
    int r;
}line[maxn];
bool cmp(node a,node b)
{
    return a.r>b.r;
}
int m;
bool vis[maxn];
int ans[maxn];
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&m);
        int x,y;
        int tot=0;
        while(scanf("%d%d",&x,&y)&&(x||y))
        {
             if(y<=0||x>=m) continue;
             line[tot].l=x;
             line[tot++].r=y;
        }
        sort(line,line+tot,cmp);
        //cout<<tot<<endl;
        int sr=0;
        memset(vis,false,sizeof(vis));//用来标记该线段有没有被使用
        memset(ans,0,sizeof(ans));
        int ant=0;
        while(sr<m)
        {
            bool flag=false;//判断是否找到
            for(int i=0;i<tot;i++)
            {
                if(!vis[i]&&line[i].l<=sr&&line[i].r>sr)
                {
                    vis[i]=true;
                    ans[ant++]=i;
                    sr=line[i].r;//更新右端点
                    flag=true;
                }
            }
           //cout<<sr<<endl;
            if(!flag) break;//未找到符合条件的线段
        }
        if(sr>=m)
        {
            printf("%d\n",ant);
            for(int i=0;i<ant;i++)
            {
                printf("%d %d\n",line[ans[i]].l,line[ans[i]].r);
            }
        }
        else  printf("0\n");
    }
}

 

posted on 2016-07-26 15:18  当蜗牛有了理想  阅读(291)  评论(0编辑  收藏  举报

导航