题目是英文,我就不放原题了,简单几句概括:
现在需要准备很多等长的网线小段。
现在从供应商那里买了一堆网线:
每根网线长度不同
可以按 1 厘米精度切割
但不能拼接(只能切)
从这些线里切出 K 段完全相同长度的网线,并且希望这些小段尽可能长
输入
第一行:
N K
N:有多少根电缆(1 ≤ N ≤ 10000)
K:需要切出的段数(1 ≤ K ≤ 10000)
接下来 N 行:
每行一个电缆长度(单位:米)
精确到小数点后两位(厘米级精度)
范围:1 m ~ 100000 m
输出
可以切出的 最大等长网线长度(米)
要求:精确到小数点后两位;如果连 1 cm 都切不出 K 段则为0.00

这是最大最小二分,小数二分,求最大值的话右缩
板子的话看老师ppt
下面是我根据板子写的一次
cpp
bool judge(double x) {
int cnt = 0;
for (int i = 0; i < n; i++) {
cnt += (int)(a[i] / x);
}
return cnt >= K;
}
double solve() {
double l = 0, r = maxLen; // 最大绳子长度
const double eps = 1e-7;
while (r - l > eps) {
double mid = (l + r) / 2;
if (judge(mid)) {
l = mid; // 可以切够 → 尝试更长
} else {
r = mid; // 不够 → 缩短
}
}
return l;
}
这是最核心的两个方法,下面是完整的
cpp
#include <iostream>
#include <iomanip>
using namespace std;
const int MAXN = 10010;
int n, k;
int len[MAXN]; // 单位:cm
bool judge(int x) {
if (x == 0) return true;
int cnt = 0;
for (int i = 0; i < n; i++) {
cnt += len[i] / x;
}
return cnt >= k;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n >> k;
int maxLen = 0;
for (int i = 0; i < n; i++) {
double x;
cin >> x;
len[i] = (int)(x * 100 + 0.5); // 转 cm
if (len[i] > maxLen) maxLen = len[i];
}
int l = 1, r = maxLen;
int ans = 0;
while (l <= r) {
int mid = (l + r) / 2;
if (judge(mid)) {
ans = mid;
l = mid + 1;
} else {
r = mid - 1;
}
}
if (ans == 0) {
cout << "0.00\n";
} else {
cout << fixed << setprecision(2) << ans / 100.0 << "\n";
}
return 0;
}