华华听月月唱歌(贪心区间覆盖问题)

链接:https://ac.nowcoder.com/acm/contest/392/A
来源:牛客网
 

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld

题目描述

月月唱歌超级好听的说!华华听说月月在某个网站发布了自己唱的歌曲,于是把完整的歌曲下载到了U盘里。然而华华不小心把U盘摔了一下,里面的文件摔碎了。月月的歌曲可以看成由1到N的正整数依次排列构成的序列,它现在变成了若干个区间,这些区间可能互相重叠。华华想把它修复为完整的歌曲,也就是找到若干个片段,使他们的并集包含1到N(注意,本题中我们只关注整数,见样例1)。但是华华很懒,所以他想选择最少的区间。请你算出华华最少选择多少个区间。因为华华的U盘受损严重,所以有可能做不到,如果做不到请输出-1。

输入描述:

第一行两个正整数N、M,表示歌曲的原长和片段的个数。
接下来M行,每行两个正整数L、R表示第i的片段对应的区间是[L,R]。

输出描述:

如果可以做到,输出最少需要的片段的数量,否则输出-1。

示例1

输入

4 2
1 2
3 4

输出

2

示例2

输入

4 2
1 1
3 4

输出

-1

示例3

输入

10 5
1 1
2 5
3 6
4 9
8 10

输出

4

备注:

1≤L≤R≤109,1≤N≤109,1≤M≤105

解析:

给定n个区间,求覆盖1~n需要最小的区间数目

用贪心解决,l从小到大排,遍历找到   l<=g中r最大的,更新

ac:

#include<bits/stdc++.h>
#define MAXN 100005
using namespace std;

struct node
{
    int l,r;
}ee[MAXN];

bool cmp(node a,node b)
{
    return a.l<b.l;
}

int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++)
        scanf("%d%d",&ee[i].l,&ee[i].r);
    sort(ee,ee+m,cmp);
    int flag=0,sum=0,i=0,g=1;
    while(i<m)
    {
        int maxs=0;
        for(i;i<m&&ee[i].l<=g;i++)//(i<m)不写会数组溢出
            maxs=max(maxs,ee[i].r);
        if(maxs==0)
            break;

        sum++;
        g=maxs+1;
        if(g>=n)
        {
            flag=1;
            break;
        }
    }
    if(flag)
        printf("%d\n",sum);
    else
        printf("-1\n");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_41183791/article/details/88383246
今日推荐