AcWing 1227. 分巧克力 java

参考地址
👨‍🏫 题意

k 个人分 i 块巧克力,见者有份,每份都是一样的,而且必须是正方形的
每块巧克力宽 W[ i ] 高 H[ i ] 
满足以上,求正方形的最大边长

👨‍🏫 不要自作聪明,不能是小块拼接成一份,只能是整块的,基本的待客礼仪还是要有的

✨ 输入

2 10
6 5
5 6

✨ 输出

2

👵 求边长

边长越大,能分割的块数越小
边长越小,能分割的块数越大

👵 二段性:找一个 支持切成 >= k 块的 所有边长中最大的边长

👵 check(mid) 求出 mid 边长 能切除多少块

当 check (mid) >= k 时,mid 符合条件,求最大的mid,所以 l = mid;
else r = mid -1; 
因为有减1,避免出现 mid = (0 + 1)/ 2 = 0 的情况,即 r = 0 - 1 = -1 越界的情况
所以  mid = ( l + r + 1 ) / 2  ⭐

🤠 二分 O( n log H)

import java.io.*;
import java.util.*;

public class 分巧克力
{
	static int N = 100010, n, k;
	static int[] W = new int[N];
	static int[] H = new int[N];
	static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
	static BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));

	public static void main(String[] args) throws IOException
	{
		String[] split = in.readLine().split(" ");
		n = Integer.parseInt(split[0]);
		k = Integer.parseInt(split[1]);
		for (int i = 0; i < n; i++)
		{
			String[] split2 = in.readLine().split(" ");
			H[i] = Integer.parseInt(split2[0]);
			W[i] = Integer.parseInt(split2[1]);
		}

		int l = 1;
		int r = 100000;
		while (l < r)
		{
			int mid = l + r + 1 >> 1;
			if (check(mid))
				l = mid;
			else
			{
				r = mid - 1;
			}
		}

		out.write(l + "");
		out.flush();
	}

	private static boolean check(int x)
	{
		int cnt = 0;// 记录能切多少块
		for (int i = 0; i < n; i++)
		{
			cnt += (H[i] / x) * (W[i] / x);
			if (cnt >= k)
				return true;
		}

		return false;
	}
}
posted @ 2023-03-05 16:38  兑生  阅读(32)  评论(0)    收藏  举报  来源
Live2D