题意理解:给定一个区间,我们需要把这个区间覆盖掉。问最少需要的区间数目。当然我们会给定 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;
}
其他
故事的结局是否重要,很多人以为的结局是这样一种场景,杂志社的编辑告诉你,还有三个月交稿,多想多看,写坏了没关系,我们时间充裕,重新再写,好好写。
其实不是。
真正的结局是某个下午,你午睡醒来,在纸上潦草画了几笔,房门忽然被敲响,来人问你写到了哪,不管上面写了什么,你有多不甘心,多想要修改,这页就是结局。
世事无常,人生不如意太多太多。
愿大家珍惜眼前人,自己所爱之人,所爱之事,认真地过完这一生,莫要后悔。
我家先生,我喜欢他多年,从高中开始,直到现在。
感触颇深。