牛客小白月赛12 B 华华听月月唱歌A

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yuewenyao/article/details/88598286

题目链接:https://ac.nowcoder.com/acm/contest/392/A

题目描述

月月唱歌超级好听的说!华华听说月月在某个网站发布了自己唱的歌曲,于是把完整的歌曲下载到了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

题意很容易理解,直接上代码吧:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
struct kk
{
    ll l , r;
}s[500500];
bool cmp(kk a , kk b)
{
    return a.l < b.l;
}
ll m , n , z = 1 , ans , q , p;
int main()
{
    while(cin >> n >> m)
    {
        ans = 0;
        for(ll i = 1 ; i <= m ; i ++)
        {
            cin >> s[i].l >>s[i].r;
        }
        sort(s+1,s+m+1,cmp);
        for(ll i = 1 ; i <= m ;)
        {
            q = 0;
            while(s[i].l <= z && i <= m)
            {
                if(s[i].r > p)
                {
                    p = s[i].r;
                    q = 1;
                }
                i ++;
            }
            if(q == 0)
                break;
            ans ++;
            z = p + 1;
            if(z > n)
                break;
        }
        if(q == 0)
            cout<<"-1"<<endl;
        else
            cout<<ans<<endl;
    }
    return 0 ;
}

猜你喜欢

转载自blog.csdn.net/yuewenyao/article/details/88598286