UVa 10020 Minimal Coverage

\(UVa\) \(10020\)

题意:

给你一个\(0\)~\(m\)的区间,然后给你若干线段,问你最少取多少线段可以将0~m完全覆盖

分析:

经典贪心模型

\(Code:\)

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;

const int maxn=100010;

struct Node
{
    int l,r;
    bool operator < (const Node& a) const
    {
        return r>a.r;
    }
}a[maxn];
template<class T>void read(T &x)
{
    bool f=0;char ch=getchar();x=0;
    for(;ch<'0'||ch>'9';ch=getchar()) if(ch=='-') f=1;
    for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
    if(f) x=-x;
}
int ans[maxn];
bool vis[maxn];
int main()
{
    int T;
    read(T);
    while(T--)
    {
        int tot=0;
        int x,y;
        int m;
        memset(ans,0,sizeof(ans));
        memset(vis,false,sizeof(vis));
        scanf("%d",&m);
        while(scanf("%d%d",&x,&y)&&(x||y))
        {
            if(y<=0||x>=m) continue;
            a[++tot].l=x,a[tot].r=y;
        }
        sort(a+1,a+tot+1);
        int r=0;
        int cnt=0;
        while(r<m)
        {
            bool flag=false;
            for(int i=1;i<=tot;++i)
            {
                if(!vis[i]&&a[i].l<=r&&a[i].r>r)
                {
                    vis[i]=true;
                    ans[++cnt]=i;
                    r=a[i].r;
                    flag=true;
                }
            }
            if(!flag) break;
        }
        if(r>=m)
        {
            printf("%d\n",cnt);
            for(int i=1;i<=cnt;++i)
            {
                printf("%d %d\n",a[ans[i]].l,a[ans[i]].r);
            }
        }
        else
        {
            printf("0\n");
        }
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/iwillenter-top1/p/11828113.html