题目出处点这里
此题求最大值的最小值,而且范围单调,可以用二分
可以先做做下面这道题:
洛谷P2678
P2678的题解
思路几乎一模一样,只不过需要注意间距除mid如果除得尽则需要减一,代码有解释
代码有解释:
package binaryFindAndAnswer;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
public class P3853 {
static int L, N, K;
static int[] arr;
public static void main(String[] args) throws IOException {
StreamTokenizer st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
st.nextToken();
L = (int) st.nval;
st.nextToken();
N = (int) st.nval;
st.nextToken();
K = (int) st.nval;
arr = new int[N];// arr初始化,实际上N+2块石头(包括头尾两块)
for (int i = 0; i < N; i++) {
st.nextToken();
arr[i] = (int) st.nval;
}
int l = 1, r = L;
while (l <= r) {
int mid = (l+r)/2;
//既然此mid可以作为最小值,那么当mid变大时,在check函数中sum可能会减小但绝不会增加
//所以mid右边一定是满足条件的,因此我们继续往左边找,看看mid能不能更小
if (check(mid)) {//此mid可以作为最小值,可能左边还有更小的满足条件,往左边找
r = mid - 1;
}
//可以先从为什么mid不能作为最小值思考
//不能作为最小值德原因是sum太大了,在check函数中当mid足够小的时候sum会越来越多,因此mid太小了
//又因为此二分1-L单调增,mid左边的都比mid小,肯定不能往左边找,因此往右边找mid,要让mid变大点满足条件
else {//此mid不能作为最小值,说明此mid太小了,往右边找
l = mid + 1;
}
}
System.out.println(r+1);
}
public static boolean check(int mid) {
int sum=0;
for (int i = 1; i < N; i++) {
if ((arr[i] - arr[i-1]) >= mid ) {
if ((arr[i] - arr[i-1]) % mid == 0) {
sum = sum + (arr[i] - arr[i-1]) / mid - 1;//恰好除得尽需要-1,比如4/2,只需要插入一个即可,而不是插入两个
}else {
sum = sum + (arr[i] - arr[i-1]) / mid;//除不尽正常插入
}
}
}
if (sum > K) {
return false;
}else {
return true;
}
}
}