题目描述
恶龙又一次摧毁了城市,愤怒的国王决定讨伐恶龙。于是他在王国四处贴上告示,征召勇者们前来讨伐恶龙。
由于恶龙十分强大,勇者再厉害也只是凡人,一个人的力量是无法打败恶龙的,但团结起来的勇者们将是不可战胜的。恶龙的血量为X,X为整数。
每个勇士都有自己擅长的地方,都可以对某一阶段(某个血量区间内)的恶龙进行致命伤害。
现在国王要从n个勇士中选出可以完全覆盖对恶龙致命伤害的勇士,最少需要几个人?
输入格式
第一行输入一个n表示有n个勇士
第2行到第n+1行输入L和R,表示第i位勇士可以造成致命伤害的血量区间
第n+1行输入X表示恶龙的血量
输出格式
覆盖范围包括恶龙全部血量区间的数量,如果无法覆盖,则输出-1。
样例
Input 1
5
0 1
1 2
2 7
7 8
8 10
10
Output 1
5
样例解释
对每个TestSample的解释(为什么这个input会得到这个output)
不用看这
数据范围
0 <= X <= 10^9
0 <= n <= 10^4
题解
题意:
给定 n 个区间,问你最少能用几个区间完整覆盖 0 ~ m
如果能完全覆盖,输出最少用几个区间
如果不能,输出 -1
解题
根据题意,我们大概能猜想出这是一道 贪心 的题目
选择相邻两个区间重复的地方尽量小,且能完全覆盖 0 ~ m
那么如何实现呢?
首先,我们是从 0 开始枚举区间的,所以要用一个结构体排序,把 l 从小到大排序
bool cmp(lr a,lr b){
return a.l < b.l;
}
然后,我们要用两个变量 l 和 r 来记录当前覆盖了多少区间
用一个 temp 来记录当前的 r (这里看不懂没关系,看后面代码理解)
然后往后枚举 a_i ,保证 a_i 的 l 不超过 temp , r=a_i 的 r
int res=0,l=0,r=0,temp=0;//res记录用了多少个区间
for(int i=1;i<=n;){
if(temp>=m) break;//已经覆盖完所有区间了
if(a[i].l>temp){//当前的r ~a[i].l的区块覆盖不到
cout<<-1;
return 0;
}
while(i<=n&&a[i].l<=temp) r=max(r,a[i].r),i++;//上文
res++;
temp=r;//刷新
}
最后加点输入输出,这道题就解决啦~