题意理解:给定一个区间,我们需要把这个区间覆盖掉。问最少需要的区间数目。当然我们会给定 n
个区间选择。假设全选都不能覆盖就输出
−
1
-1
−1
思路分析:我感觉应该是找区间的端点。假设区间的左端点是 s
,右端点是 t
,我们枚举的区间的左端点尽可能靠近 s
,右端点尽可能靠近 t
,这样的贪心策略就可以使得选择的区间数目,还需要检测区间内部是不是完整地被覆盖了。需要枚举的区间按照左端点排序。选择的是那个最靠近 s
的区间作为选择的第一个区间。更新的思路是找最大的左端点,让这个左端点小于等于前面选择的区间的右端点,这样才能保证被覆盖了。最后要判断区间的右端点要超过 t
这个点,但是不能超过太多。但是我们贪心只能从一端开始贪心,是不是要从左边往右边贪心一遍,然后从右边往左边贪心一次,然后取一个最小值呢。
看了一下题解,好像和我的思路不是太像,但是有一些相似之处,毕竟同一题,不过思路和实现之间隔着一个银河系,感觉,我没啥信心把这题写出来。
#include<iostream>
#include<algorithm>
using namespace std;
const int N=100000+10;
int n;
int st,ed;
struct Range{
int l,r;
bool operator< (const Range &W)const{
return l<W.l;
}
}range[N];
int main(){
scanf("%d%d",&st,&ed);
scanf("%d",&n);
for(int i=0;i<n;i++){
int l,r;
scanf("%d%d",&l,&r);
range[i]={l,r};
}
sort(range,range+n);
int ans=0;
bool success=false;
for(int i=0;i<n;i++){
int j=i;
int r=-2e9;
while(j<n&&range[j].l<=st){
r=max(r,range[j].r);
j++;
}
if(r<st){
break;//表示不可能覆盖掉
}
ans++;
if(r>=ed){
success=true;
break;
}
st=r;
i=j-1;//假设现在的 j 比较到某一位了,找到了一个最大值,然后我们更新了 st
//我们需要枚举下一个区间,但是这个时候已经不满足条件了,所以需要返回前面那个
//满足条件的区间,应该是这个意思,对的,就是现在下一个区间的左端点没在 st 的左边
//得更新 st
}
if(!success){
ans=-1;
}
printf("%d\n",ans);
return 0;
}
其他
故事的结局是否重要,很多人以为的结局是这样一种场景,杂志社的编辑告诉你,还有三个月交稿,多想多看,写坏了没关系,我们时间充裕,重新再写,好好写。
其实不是。
真正的结局是某个下午,你午睡醒来,在纸上潦草画了几笔,房门忽然被敲响,来人问你写到了哪,不管上面写了什么,你有多不甘心,多想要修改,这页就是结局。
世事无常,人生不如意太多太多。
愿大家珍惜眼前人,自己所爱之人,所爱之事,认真地过完这一生,莫要后悔。
我家先生,我喜欢他多年,从高中开始,直到现在。
感触颇深。