1.小红的花圃抬高方案

核心思路
对于给定的目标高度h,需要计算:
-
总土量 = sum(max(0, h - heighti))
-
需要的车数 = ceil(总土量 / C)
-
总成本 = 总土量 * U + 车数 * F
-
判断成本是否 ≤ B
然后用二分查找找到最大可行高度。
代码实现
java
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
// 读取输入
long B = in.nextLong(); // 预算
long C = in.nextLong(); // 每车容量
long F = in.nextLong(); // 每车运输费
long U = in.nextLong(); // 单位填埋费
int n = in.nextInt(); // 花圃数
long[] heights = new long[n];
long minHeight = Long.MAX_VALUE;
long maxHeight = Long.MIN_VALUE;
for (int i = 0; i < n; i++) {
heights[i] = in.nextLong();
minHeight = Math.min(minHeight, heights[i]);
maxHeight = Math.max(maxHeight, heights[i]);
}
// 二分查找:下界是最低高度,上界可以设置得足够大
// 最坏情况:把最低的抬高到 maxHeight + B/U(但实际受预算限制)
long left = minHeight;
long right = maxHeight + 1000000000L; // 设置一个足够大的上界
long ans = minHeight;
while (left <= right) {
long mid = left + (right - left) / 2;
if (check(mid, heights, B, C, F, U)) {
ans = mid;
left = mid + 1; // 尝试更高的高度
} else {
right = mid - 1; // 降低高度
}
}
System.out.println(ans);
}
// 检查是否能将所有花圃抬高到目标高度
private static boolean check(long target, long[] heights, long B, long C, long F, long U) {
long totalSoil = 0;
// 计算需要的总土量
for (long h : heights) {
if (h < target) {
totalSoil += target - h;
}
}
// 如果不需要土,成本为0
if (totalSoil == 0) {
return true;
}
// 计算需要的车数:向上取整
long trucks = (totalSoil + C - 1) / C;
// 计算总成本
long cost = totalSoil * U + trucks * F;
return cost <= B;
}
}
代码说明
-
输入读取:按照题目顺序读取 B, C, F, U, n 和 n 个高度
-
二分查找:
-
left设为最低高度(保证至少能达到当前最低高度) -
right设为一个足够大的值 -
每次检查 mid 是否可行
-
-
检查函数 check:
-
计算所有花圃抬高到 target 所需的总土量
-
计算需要的车数(向上取整)
-
计算总成本并判断是否在预算内
-
-
输出答案:二分结束后输出最大的可行高度
注意事项
-
使用
long类型避免溢出(B 最大 10^11,计算过程中可能超过 int 范围) -
(totalSoil + C - 1) / C是整数向上取整的经典写法 -
二分上界设置要足够大,考虑到最多可能抬高到初始最高高度 + 预算/单位填埋费