来自 <[NOIP2015 提高组] 跳石头 - 洛谷>
题意:
题目就是说有在起点和终点里面有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;}}
}