![](https://i-blog.csdnimg.cn/blog_migrate/308aa1e9c0c6b542639bedd377b2f367.png)
题意:
题目就是说有在起点和终点里面有5个石头,现在让你移出两个石头,要移哪两个可以满足最后最短距离最长。假如现在要移11位置和14位置的两块石头,最后的最短距离是2,而如果移的是2位置和14位置的两块石头,最后的最短距离是4。因此我们认为4是我们的最长最短距离。
思路:
而如果我们正面去想如何移是一件很难的事,我们可以从最短距离的角度去思考。我们知道最短距离的长度无非就是0到25这个区间内的,所以我们可以暴力假设,如果最短距离为1可不可以成立,如果最短距离是2可不可以成立…….
但我们可以直接二分取中间值来假设,假如最短距离取(0+25)/2=12;然后扫描整个装着石头的数组,如果距离小于12,那么我们就取石头,然后计数,如果计数值超过题目规定的,说明这个最短距离长度不满足。所以r=mid-1;反之,如果成立,我们会继续扩大我们的最短距离,毕竟题目中要的是最长的。l=mid。
代码:
import java.util.Scanner;
public class Main {
public static int L;
public static int N;
public static int M;
public static int[] a=new int[50010];
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
L=scan.nextInt();
N=scan.nextInt();
M=scan.nextInt();
a[0]=0;a[N+1]=L;
for(int i=1;i<=N;i++){
a[i]=scan.nextInt();
}
int l=0,r=L;
while(l<r){
int mid=(l+r+1)/2;
if(judge(mid)){//如果成立,我们会继续扩大我们的最短距离,毕竟题目中要的是最长的
l=mid;
}
else {
r=mid-1;
}
}
System.out.println(l);
}
public static boolean judge(int shortDistance){
int now=0;
int cnt=0;
for(int i=1;i<=N+1;i++){
if(a[i]-a[now]<shortDistance){//扫描整个装着石头的数组,如果距离小于12,那么我们就取石头,然后计数
cnt++;
}
else {
now=i;
}
}
if(cnt>M){//如果计数值超过题目规定的,说明这个最短距离长度不满足
return false;
}
else {
return true;
}
}
}