洛谷 P1577:切绳子 ← 浮点数二分

【题目来源】
https://www.luogu.com.cn/problem/P1577
https://www.acwing.com/problem/content/682/

【题目描述】
有 N 条绳子,它们的长度分别为 Li。如果从它们中切割出 K 条长度相同的绳子,这 K 条绳子每条最长能有多长?答案保留到小数点后 2 位(直接舍掉 2 位后的小数)。

【输入格式】
第一行两个整数 N 和 K,接下来 N 行,描述了每条绳子的长度 Li。​​​​​​​

【输出格式】
切割后每条绳子的最大长度。答案与标准答案误差不超过 0.01 或者相对误差不超过 1% 即可通过。​​​​​​​

【输入样例】
4 11
8.02
7.43
4.57
5.39​​​​​​​

【输出样例】
2.00​​​​​​​

【数据范围】
对于 100% 的数据 0<Li≤100000.00,0<n≤10000,0<k≤10000​​​​​​​

【算法分析】
● 因为浮点数的精度很高,只需要逐渐逼近题目要求的精度就可以了。这里需要注意的是,需要预先设定一个阈值 eps,一般是比题目的精度还要高 2 位,比如题目要求的精度是1e-2,那么就可以设eps=1e-4。如本题中的 while(ri-le>1e-4){……}。

● 当数据比较大时,可能会产生溢出。所以,本题中使用 double mid=le+(ri-le)/2; 而不是 double mid=(le+ri)/2; 

● 将用“AcWing 680:剪绳子 → https://blog.csdn.net/hnjzsyjyj/article/details/136774256”中的数组a[] 的类型改为 double 型,便可复用于本题。

【算法代码:浮点数二分

#include <bits/stdc++.h>
using namespace std;

const int N=1e5+5;
double a[N];
int n,m;
bool check(double len) {
    int ans=0;
    for(int i=0; i<n; i++) {
        ans+=a[i]/len;
        if(ans>=m) return true;
    }
    return false;
}

int main() {
    cin>>n>>m;
    for(int i=0; i<n; i++) cin>>a[i];
    double le=0;
    double ri=1e9;
    while(ri-le>1e-4) {
        double mid=le+(ri-le)/2;
        if(check(mid)) le=mid;
        else ri=mid;
    }
    printf("%.2f",le);
}


/*
in:
4 11
8.02
7.43
4.57
5.39

out:
2.00
*/





【参考文献】
https://blog.csdn.net/hnjzsyjyj/article/details/136774256

 

posted @ 2026-08-04 21:43  Triwa  阅读(7)  评论(0)    收藏  举报