这个问题可以用二分搜索法来解决。我们需要找到最大的月饼高度 h
,使得可以用给定的原材料切割出至少 K
个高度为 h
的月饼。
我们可以如下进行:
-
初始化最低高度
low
为0
(因为月饼高度至少为1
,但我们从0
开始因为二分搜索将会计算中间值),最高高度high
为原材料中的最大值。 -
执行二分搜索:
-
找到
low
和high
的中间值mid
。 -
计算当前
mid
高度可以切割出多少个月饼。这可以通过遍历每块原材料,将其高度除以mid
并累加得到。 -
如果我们能切割出大于或等于
K
个月饼,那么我们知道可以有更大的mid
值,因此更新low = mid + 1
。 -
如果不能切割出足够的月饼,我们需要降低
mid
值,所以更新high = mid - 1
。
-
-
继续步骤2直到
low
大于high
。最终的结果(最大高度)就是high
,因为我们在最后一次检查能够得到K
个月饼时更新了low
,导致low
变得太大。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
int N, K;
cin >> N >> K;
vector<int> materials(N);
for (int i = 0; i < N; ++i) {
cin >> materials[i];
}
long long low = 1, high = *max_element(materials.begin(), materials.end());
long long result = -1;
while (low <= high) {
long long mid = low + (high - low) / 2;
long long count = 0;
for (int h : materials) {
count += h / mid;
}
if (count >= K) {
result = mid; // 更新结果为当前mid值
low = mid + 1; // 尝试更大的高度
} else {
high = mid - 1; // 减少高度以增加月饼数量
}
}
cout << result << endl;
return 0;
}
这段代码将检查所有可能的高度,直到找到可以用来切割至少 K
个月饼的最大高度。需要注意的是,如果输入的 K
大于所有材料的总高度,那么不可能制作出 K
个月饼,因此二分搜索会返回 -1
。