680. 剪绳子

 

有N根绳子,第i根绳子长度为LiLi,现在需要M根等长的绳子,你可以对N根绳子进行任意裁剪(不能拼接),请你帮忙计算出这M根绳子最长的长度是多少。

输入格式

第一行包含2个正整数N、M,表示原始绳子的数量和需求绳子的数量。

第二行包含N个整数,其中第 i 个整数LiLi表示第 i 根绳子的长度。

输出格式

输出一个数字,表示裁剪后最长的长度,保留两位小数。

数据范围

1N,M1000001≤N,M≤100000,
0<Li<1090<Li<109

输入样例:

3 4
3 5 4

输出样例:

2.50

样例解释:

第一根和第三根分别裁剪出一根2.50长度的绳子,第二根剪成2根2.50长度的绳子,刚好4根。

 

题解:

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

int n,m;
int a[N];
bool check(double mid){
    int cnt=0;
    for(int i=0;i<n;i++)
    {
        cnt+=a[i]/mid;
    }
    return cnt>=m;

}
int main(){
    cin >> n >> m;
    for(int i=0;i<n;i++)
    {
        cin >> a[i];
    }
    double r=0,l=1e9;
    while(l-r>=1e-4)
    {
        double mid=(l+r)/2;
        if(check(mid))
        {
            r=mid;

        }
        else{
            l=mid;

        }


    }
    printf("%.2f\n",r);

    system("pause");



}

 

思考:

浮点数二分相比于整数二分,不用考虑边界问题,较为简单。二分法的核心思想在于逐步缩小并确定数的范围,进而根据精度求出相应的数。本题,直接进行最优化求解难以求出,但通过转换思路,用二分法确定出所求的绳子长度并进行判断是容易做到的。因此,我们先确定绳子取值的边界,然后通过---取mid---判断该mid所对应的m值与要求的m值的大小关系---如果m'>=m,则取二分右部区间,左端点变为mid---如果m'<=m,则取二分左部区间,右端点变为mid。遍历判断,直到找到符合精度要求的值为止。

posted on 2021-01-15 00:12  Ni_o  阅读(77)  评论(0)    收藏  举报