AcWing 680.剪绳子

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;
}
原文地址:https://www.cnblogs.com/Lngstart/p/14277097.html