AcWing 680.剪绳子
原题链接
解题思路
因为要求的是能够满足m条数量的最大绳子的裁剪长度,所以找出数组中的最大值r,使其在0~r中使用浮点数二分,看分成的绳子的数量是否符合要求,如果分成的绳子的数量大于m,则表示绳子还能再分长,令l=mid,反之则令r=mid。最后符合某一精度的两个端点l,r都可以是答案。
每一次二分看能够向哪个方向二分,当到达精度要求的时候其端点就是结果
代码如下
#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
int n, m;
int a[N];
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int n, m; cin >> n >> m;
for(int i = 0; i < n; ++ i) cin >> a[i];
double max_val = -1;
for(int i = 0; i < n; ++ i) max_val = max(max_val, (double)a[i]);
//浮点数二分
// double ret = -1;//这个可以不用记录,因为多了就向后分,少了就向前分,最后再精度范围内的两个端点都是对的
double min_val = 0;
while(max_val - min_val >= 1e-4){
double mid = (min_val + max_val) / 2;
int res = 0;
for(int i = 0; i < n; ++ i){
res += (int)(a[i] / mid);
}
if(res >= m){//如果分成的数量大于m,证明还可能可以增加长度,反之亦然
// ret = max(ret, mid);
min_val = mid;
}else max_val = mid;
}
printf("%.2lf", max_val);
return 0;
}