Cable master(电缆总管)

题意:

给出n条线段,以米的单位给出,小数点后两位(精确到厘米),要对这些线段裁剪,裁剪出m条等长的线段,返回最长的线长。

输入:

输入文件的第一行包含两个整数 N 和 K,用空格分隔。N (1 = N = 10000) 是库存中的电缆数量,K (1 = K = 10000) 是请求的件数。第一行后面是 N 行,每行一个数字,指定库存中每根电缆的长度(以米为单位)。所有电缆的长度至少为 1 米,最长为 100 公里。输入文件中的所有长度都以厘米精度写入,小数点后正好有两位数字。

输出:

将 Cable Master 可以从库存中的电缆切割以获得所需件数的最大长度(以米为单位)写入输出文件。该数字必须以厘米精度书写,小数点后恰好有两位数字。
如果无法切割要求的每件至少一厘米长的件,则输出文件必须包含单个数字“0.00”(不带引号)。
 

学习笔记: 

本题思路不难,就是二分法,但是本题有很多细节要注意:

1.最长的电缆是100公里,不是100米,可别看错了

2.不足一厘米的部分要去掉,也就是说,不是四舍五入,必须向下取整。这个可以用floor函数实现,它会对一个浮点数向下取整。

3.小数进行二分是没有尽头的,所以要设置终止条件,一般有两种办法:第一种是设定循环次数,一般循环100次是足够的,第二种是设定最大差值eps,当左右边界的差值小于eps的时候说明精度足够了,我个人偏向第二种做法。但是要特别注意的是,eps不能设置的太小,不然如果小于double的精度的话会导致死循环问题。一般eps设为1e-7即可。

4.cin貌似不能用来输入浮点数?(我不太确定,但是我把scanf换成cin就TLE了,不知道是有什么问题)

代码:

#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <string.h>
#include <climits>
typedef long long ll;
using namespace std;
const int MAXN = 1e4+5;
const double eps = 1e-7;

int n; // 绳子数量
int k; //要求分成的段数
double L[MAXN]; // 记录所有绳子长度的数组

int isEnough(double x){
    int sum = 0;
    for(int i=0; i<n; i++){
        sum += (int)(L[i] / x);
    }
    return sum >= k;
}

int main(){
    scanf("%d%d", &n, &k);
    for(int i=0; i<n; i++){
        scanf("%lf", &L[i]);
    }
    double lb = 0.0, ub = 1e5+5;
    while(ub - lb > eps){
        double mid = (lb + ub) / 2;
        if(isEnough(mid)) lb = mid;
        else ub = mid;
    }
    printf("%.2f\n", floor(ub*100)/100);
}

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值