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;
}
}

浙公网安备 33010602011771号