笔试题1

题目描述: 有N根绳子,第i根绳子长度为L1,现在需要M根等长的绳子,你可以对N根绳子进行裁剪(不能拼接),请你帮忙计算出这M根绳子的最长的长度是多少?

如果最长的绳子足够长,那么就可以满足M根等长的绳子,所以二分搜索加贪心验证,二分绳子长度加判断是否满足。

二分长度,简单算下N*log(L)应该是可以过,所以二分最大长度,朴素的check是否满足就可以了

思路:能否等分出m个长度为L的绳子,在l ∈ [0, L] 上是个不减问题,即如果某个满足此条件的最大位置为l,则大于l的无法等分,小于l的可以等分
因此,二分满足题意的L,找到最大位置判断即可,复杂度已经算过是OK的,注意停止条件和输出位数有关;以及边界问题(r减 l不增,因为k是满足的)
 


#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
using namespace std;
int n, m, x;
vector<double> a;
inline bool check(double l){
    int count = 0;
    for(int i = n - 1; i >= 0 && a[i] >= l; --i){
        count += floor(a[i] / l);
    }
    return count >= m;
}
inline double solve(int m){
    double l = 0.f, r = a[n-1] + 1.f;
    while( r - l > 1e-3){
        double k = (l + r) / 2;
        if (check(k))
            l = k;
        else
            r = k - 0.001;
    }
    return l;
}
int main(){
    scanf("%d%d", &n, &m);
    for(int i = 0; i < n; ++i){
        scanf("%d", &x);
        a.push_back((double)x);
    }
    sort(a.begin(), a.end());
    printf("%.2lf", solve(m));
    return 0;
}
原文地址:https://www.cnblogs.com/xianbin7/p/10549270.html