通过率 47% · 提交 757 · 通过 359
小慕有 n 块木板,第 i (1 ≤ i ≤ n) 块木板的长度为 ai。 小慕有一根长度为 m 的木料,这根木料可以切割成任意块,,用来加长木板。 小慕希望让最短的木板尽可能长。请问小慕加长木板后,最短木板的长度最大可以是多少?
这类题属于华为 OD 机考真题方向中「100分 / 贪心」方向的高频题型,通常考察对「100分 / 贪心」的建模能力与边界条件处理。掌握本题的解题思路后,可举一反三应对同类真题方向,稳步提升机考通过率。
提示:带虚线的词点一下有通俗解释。
输入的第一行包含两个正整数, n ( 1 ≤ n ≤ 10^3 ), m ( 1 ≤ m ≤ 10^6 ),n 表示木板数, m 表示木板长度。 输入的第二行包含 n 个正整数, a1, a2,…,an ( 1 ≤ ai ≤ 10^6 )。
输出的唯一一行包含一个正整数,表示加长木板后,最短木板的长度最大可以为多少?
示例 1
输入示例
5 3 4 5 3 5 5
输出示例
5
给第1块木板长度增加1,给第3块木板长度增加2后,这5块木板长度变为[5,5,5,5,5],最短的木板的长度最大为5。
示例 2
输入示例
5 2 4 5 3 5 5
输出示例
4
给第3块木板长度增加1后,这5块木板长度变为[4,5,4,5,5],剩余木料的长度为1。此时剩余木料无论给哪块木板加长,最短木料的长度都为4。
时间限制 1000 ms · 内存限制 128 MB
本平台为独立第三方培训机构,与华为技术有限公司无任何关联;课程的服务内容与权益以购买协议为准,学习效果因个人情况而异。「华为 OD」「华为可信」等仅为对岗位与考试方向的客观描述,相关商标归各自权利人所有。
本题其实暗含一些贪心思想,但想到思路后更多考察的是代码细节上的实现,因此将本题归类为模拟类型。
很容易想到,我们肯定要优先填充最短的那一块木板。因此,我们不妨先对所有木板进行从小到大排序。
对于例子:
我们对所有木板排序得到如下所示:
在填充最短木板(高度为 3)的时候,我们先将它填充到跟第二短的木板(高度为 5)一样的高度。会得到以下结果:
填充完毕后,我们发现剩余木板长度还剩下 5,还可以继续进行填充。这个时候我们会继续考虑当前两个最短长度的木板(高度为 5)的填充,将它们填充到第三短的木板(高度为 7)的高度。会得到以下结果:
此时剩余木板长度为 1,但是此时我们存在 3 个长度为 7 的最短木板,无法再使得这三个最短木板的高度同时增加,因此正确答案为 7。
如果我们所有的木板都遵循类似的贪心策略,每次补齐都只把木板补齐到下一个更长木板的高度。
当我们从小到大地考虑第 i 块木板的时候(它的高度是 heights[i]),此时必然存在已经有 i 块前面的木板都已经补齐到高度 heights[i] 了,包括这块木板自身,一共有 i+1 块木板的高度为 heights[i]。而下一个更长木板的高度为 heights[i+1],如果想要把这 i+1 块木板的高度都补齐到 heights[i+1] 的话,一定需要 (heights[i+1] - heights[i]) * (i+1) 的木板材料。
假设此时剩余木板材料的高度为 rest。若:
rest > (heights[i+1] - heights[i]) * (i+1),则所有高度为 heights[i] 的木板都可以补到 heights[i+1] 的高度,我们还需要继续往下循环。rest <= (heights[i+1] - heights[i]) * (i+1),则所有高度为 heights[i] 的木板无法补齐到 `heights[i+1]` 的高度。由于存在 (i+1) 块等高的木板,它们需要尽量地补到同一高度,它们最多每块只能增加 rest // (i+1) 的高度,而最终的总高度为 `heights[i] + rest // (i+1)`。那么我们的代码可以这样完成:
其中语句 heights.append(2 * 10**6) 是给 heights 数组末尾填充一个极大的数字,表示一个长度极大的木板。其作用是当我们处理 rest 极大,远超所有木板都补充到最长木板 max(heights) 所需要的消耗的情况。在那种情况下,我们会考虑此时一共 n 块高度为 max(heights) 的木板将如何补充到一个均匀的高度,也同样会执行 ans = heights[i] + rest // (i+1) 代码得到答案。
复杂度分析 设 n 为木板数量。
登录后可查看你在本题的历史提交,以及每次的各用例通过情况。
© 2026 广州慕课网络科技有限公司 · 吴师兄学算法官网 版权所有