(今日头条面试题)剪绳子(二分带详细思路)

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

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

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

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

数据范围
1≤N,M≤100000
0<Li<109次方
输入样例:
3 4
3 5 4
输出样例:
2.50
样例解释
第一根和第三根分别裁剪出一根2.50长度的绳子,第二根剪成22.50长度的
绳子,刚好4根。
思路:首先直接做不好做,那么想想暴力,确定绳子长度那么总共切几块就知道了!
将绳子长度从大到小枚举,第一个满足能切m条的就是满足条件的最大长度即可

然后优化,就是发现他有单调性,可以用二分,比如 如果一个长度
切出来大于等于m条,那么比这个长度小的都满足,在这个长度到右边界找答案
#include<bits/stdc++.h>
using namespace std;
const int N=100010;
int a[N];
int n,m;
int get(double x){
    
    //注意精度
    int sum=0;
    for(int i=0;i<n;i++){
    
    
        sum+=a[i]/x;
    }
    return sum;
}
int main(){
    
    
    cin>>n>>m;
    int maxn=-1;
    for(int i=0;i<n;i++){
    
    
        scanf("%d",&a[i]);
        if(a[i]>maxn){
    
    
            maxn=a[i];
        }
    }
    double l=0,r=maxn;
    while(r-l>1e-6){
    
    
        double mid=(l+r)/2;
        if(get(mid)>=m)l=mid;
        else r=mid;
    }
    printf("%.2f",l);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43738331/article/details/112645447