牛客小白月赛12 -- A 华华听月月唱歌 (贪心区间覆盖)

链接: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

题解 : 

考虑贪心,将所有区间按照左端点排序,从左往右遍历。用一个变量维护我们当前最远可以够到的右端点,然后枚举左端点不超过右端点+1的所有区间,选择右端点最靠右的一个即可。时间复杂度O(NlogN)。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <cmath>
#include <algorithm>
using namespace std ;
typedef long long LL;
const LL mod = 1e9+10 ;
const int MAX = 2e5+10 ;
const int inf = 1e9+10 ;
struct node {
	int l ;
	int r ;
};
node a[MAX] ;
bool cmp(const node &a ,const node &b ){
	return a.l < b.l ;
}
int main(){
	int n , m ;
	cin >> n >>m  ;
	for(int i  = 1; i<=m ; i++ ){
		cin >> a[i].l>>a[i].r ;
	}
	sort(a+1,a+1+m,cmp) ;
	int now = 0 ,cnt = 0 , idx = 1  ;
	while(idx<=m){
		if(now >=n ) break ;
		int tmp = now ;
		while(idx<=m && a[idx].l <=now+1 ){
			tmp = max(tmp,a[idx].r) ; // 最右端点
			idx++ ;
		}
		if(tmp >now ){
			now = tmp ;
			cnt++ ;
		}
		else{
			// 出现断点
			break ;
		}
	}
	if(now <n ) cout<<"-1"<<endl ;
	else cout<<cnt<<endl ;
    return 0;
}
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <cmath>
#include <algorithm>
using namespace std ;
typedef long long LL;
const LL mod = 1e9+7 ;
const int MAX = 100055 ;
const int inf = 0x3f3f3f3f ;
struct node {
    int s ,e ;
    bool operator <(const node nt) const {
    return s < nt.s  ; }
}cow[MAX];
 
int main(){
    int n , m ;  ;
    cin >> n >> m  ;
    for(int i = 0 ; i <m ; i++ ){
        cin >> cow[i].s >>cow[i].e ;
    }
    sort(cow,cow+m) ;
    int start_ = 1 , end_ =1 , cnt = 1 ;
    for(int i = 0 ; i<m ; i++ ){
        if(cow[i].s<=start_){
            end_ = max(end_,cow[i].e) ;
        }
        else{
            cnt++ ;
            start_ =end_+ 1 ;
            if(cow[i].s <=start_){
                end_ = max(end_,cow[i].e) ;
            }
            else{
                cout<<"-1"<<endl ;
                return 0 ;
            }
        }
        if(end_ >=n ){
            break ;
        }
    }
    cout<<cnt ;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41661809/article/details/88375833