洛谷P3853 Java解法

题目出处点这里
在这里插入图片描述
此题求最大值的最小值,而且范围单调,可以用二分
可以先做做下面这道题:
洛谷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;
		}
		
	}
}

猜你喜欢

转载自blog.csdn.net/TXXERIN/article/details/107443626