三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

春秋招笔试题总结

春秋招笔试题总结

1.小红的花圃抬高方案

核心思路

对于给定的目标高度h,需要计算:

  1. 总土量 = sum(max(0, h - height[i]))

  2. 需要的车数 = ceil(总土量 / C)

  3. 总成本 = 总土量 * U + 车数 * F

  4. 判断成本是否 ≤ B

然后用二分查找找到最大可行高度。

代码实现

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

代码说明

  1. 输入读取:按照题目顺序读取 B, C, F, U, n 和 n 个高度

  2. 二分查找

    • left设为最低高度(保证至少能达到当前最低高度)

    • right设为一个足够大的值

    • 每次检查 mid 是否可行

  3. 检查函数 check

    • 计算所有花圃抬高到 target 所需的总土量

    • 计算需要的车数(向上取整)

    • 计算总成本并判断是否在预算内

  4. 输出答案:二分结束后输出最大的可行高度

注意事项

  • 使用long类型避免溢出(B 最大 10^11,计算过程中可能超过 int 范围)

  • (totalSoil + C - 1) / C是整数向上取整的经典写法

  • 二分上界设置要足够大,考虑到最多可能抬高到初始最高高度 + 预算/单位填埋费

← 返回列表