目录
题目
原题地址:木材加工-Vijos
问题描述
木材厂有一些原木,现在想把这些木头切割成一些长度相同的小段木头(木头有可能有剩余),需要得到的小段的数目是给定的。当然,我们希望得到的小段越长越好,你的任务是计算能够得到的小段木头的最大长度。木头长度的单位是cm。原木的长度都是正整数,我们要求得到的小段木头的长度也是正整数。
例如有两根原木长度分别为 11 和 21,要求切割成等长的 6 段,很明显能切割出来的小段木头长度最长为 5。
Input
3 7 232 124 456
Output
114
解题思路
此题中,我们采用二分答案实现。
二分什么?
二分能够切割得到的小段的最大长度。
如何 check ?
首先,定义check函数:
bool check(int x) { //x代表了能够切割得到的小段的最大长度
从 n 个木材中依次取出每根木材,计算每根木材构造量的方法为:
L[i] / x
那么,check 函数得解:
bool check(int x) { //x代表能够切割得到的小段的长度
int s = 0;
for (int i = 1; i <= N; i++) {
s += L[i] / x;
}
return s >= K;
}
二分也就随即出来了:
int l = 1, r = maxx; //maxx是全部木材中最长的那一根长度
while (l + 1 < r) {
int mid = (l + r) >> 1;
if (check(mid)) l = mid;
else r = mid - 1;
}
My Code:
#include <bits/stdc++.h>
using namespace std;
int N, K;
int L[100010];
int read() {
cin >> N >> K;
int ret = 0;
for (int i = 1; i <= N; i++) {
cin >> L[i];
ret = max(ret, L[i]);
}
return ret;
}
bool check(int x) {
int s = 0;
for (int i = 1; i <= N; i++) {
s += L[i] / x;
}
return s >= K;
}
int main() {
int maxx = read();
if (!check(1)) {
cout << 0 << "\n";
return 0;
}
int l = 1, r = maxx;
while (l + 1 < r) {
int mid = (l + r) >> 1;
if (check(mid)) l = mid;
else r = mid - 1;
}
if (check(r)) cout << r << "\n";
else cout << l << "\n";
return 0;
}
完结ACACAC!