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