题目
给定N个闭区间[ a i , b i a_i,b_i ai,bi]以及一个线段区间[ s , t s,t s,t],请你选择尽量少的区间,将指定线段区间完全覆盖。输出最少区间数,如果无法完全覆盖则输出-1。
输入格式
第一行包含两个整数s和t,表示给定线段区间的两个端点。第二行包含整数N,表示给定区间数。
心
接下来N行,每行包含两个整数
a
i
,
b
i
a_i,b_i
ai,bi,表示一个区间的两个端点。
输出格式
输出一个整数,表示所需最少区间数。
如果无解,则输出-1。
数据范围
1
≤
N
≤
1
0
5
1 \le N \le 10^5
1≤N≤105,
−
1
0
9
≤
a
i
≤
b
i
≤
1
0
9
-10^9 \le a_i \le b_i \le 10^9
−109≤ai≤bi≤109,
−
1
0
9
≤
s
≤
t
≤
1
0
9
-10^9 \le s \le t \le 10^9
−109≤s≤t≤109
- 输入样例:
1 5
3
-1 3
2 4
3 5
- 输出样例:
2
题解
import javafx.util.Pair;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;
/**
* @author akuya
* @create 2023-07-18-19:38
*/
public class SectionCover {
static int N=10010;
static int n;
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
int st,ed;
st=scanner.nextInt();
ed=scanner.nextInt();
n=scanner.nextInt();
Pair<Integer,Integer> p[]=new Pair[N];
for(int i=0;i<n;i++){
int a=scanner.nextInt();
int b=scanner.nextInt();
p[i]=new Pair<>(a,b);
}
Arrays.sort(p,0,n, new Comparator<Pair<Integer, Integer>>() {
@Override
public int compare(Pair<Integer, Integer> o1, Pair<Integer, Integer> o2) {
return o1.getKey()-o2.getKey();
}
});
int res=0;
boolean success=false;
for(int i=0;i<n;i++){
int j= i;
int r=-2*1000000000;//c++使用-2e9
while(j<n&&p[j].getKey()<=st){
r=Math.max(r,p[j].getValue());
j++;
}
if(r<st){
res=-1;
break;
}
res++;
if(r>=ed){
success=true;
break;
}
st=r;
i=j-1;
}
if(!success) res=-1;
System.out.println(res);
}
}
思路
具体贪心思路如下图所示
这道题如何实现同样也很考验基本功,如何运用双指针确保每次所取的区间满足小于上个区间的右端点且自身的右端点最大。具体实现方法就如题解所示。