洛谷P2440 木材加工
木材加工
题目背景
要保护环境
题目描述
木材厂有 根原木,现在想把这些木头切割成 段长度均为 的小段木头(木头有可能有剩余)。
当然,我们希望得到的小段木头越长越好,请求出 的最大值。
木头长度的单位是 ,原木的长度都是正整数,我们要求切割得到的小段木头的长度也是正整数。
例如有两根原木长度分别为 和 ,要求切割成等长的 段,很明显能切割出来的小段木头长度最长为 。
输入格式
第一行是两个正整数 ,分别表示原木的数量,需要得到的小段的数量。
接下来 行,每行一个正整数 ,表示一根原木的长度。
输出格式
仅一行,即 的最大值。
如果连 长的小段都切不出来,输出 0。
样例 #1
样例输入 #1
3 7
232
124
456样例输出 #1
114提示
数据规模与约定
对于 的数据,有 ,,。
思路
和P1873 [COCI 2011/2012 #5] EKO / 砍树 - 洛谷类似,容易想到暴力枚举,但考虑数据范围,暴力枚举会超时,应使用时间复杂度更优的算法。因答案所在区间满足单调性,容易想到二分答案,用二分答案即可解。这个基本上就改那道题的check函数就行了
check函数,这里写匿名函数,不懂匿名函数的自行补全成 C 函数就好,就是标头不一样
[&](auto &&mid) { //bool check(int mid) {
i64 h = 0;
for (auto &&i : arr)
if(mid != 0)
h += i / mid;
else
isNotZero = false;
return h >= m;
}这里用到C++20的ranges库的二分答案函数,不会的自己搓二分模板也行
C++20代码
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
i64 n, m, isNotZero = (cin >> n >> m, true);
vector arr(n, 0ll);
for (auto &&i : arr)
cin >> i;
cout << *ranges::partition_point(
views::iota(0ll, *max_element(arr.begin(), arr.end())),
[&](auto &&mid) {
i64 h = 0;
for (auto &&i : arr)
if(mid != 0)
h += i / mid;
else
isNotZero = false;
return h >= m;
}) - isNotZero;
return 0;
}洛谷P2440 木材加工
https://winterl-blog.netlify.app/2023/12/24/洛谷P2440 木材加工/