切绳子 (洛谷P1577)

切绳子

题目描述

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

输入格式

第一行两个整数 N N N K K K,接下来 N N N 行,描述了每条绳子的长度 L i L_i Li

输出格式

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

样例 #1

样例输入 #1

4 11
8.02
7.43
4.57
5.39

样例输出 #1

2.00

提示

对于 100 % 100\% 100% 的数据 0 < L i ≤ 100000.00 , 0 < n ≤ 10000 , 0 < k ≤ 10000 0<L_i\leq 100000.00,0<n\leq 10000,0<k\leq 10000 0<Li100000.00,0<n10000,0<k10000

代码

#include <iostream>
using std::cin, std::cout;
int n, k; // n 是绳子的条数, k 是切割后绳子的条数
double len[10005]; // len 数组用来存储每条绳子的长度
const double esp = 1e-4; // esp 是精度的限制
bool check(double length) // 判断切割后是否有 k 条绳子的长度为 length
{
    int count = 0; // 切割后长度为 length 的绳子的总数
    for (int i = 0; i < n; i++)
        count += int (len[i] / length); // 抛弃绳子上切割后余下的部分
    return (count >= k); // 如果切割后绳子的总数大于等于 k ,则返回真
}
int main()
{
    cin >> n >> k; // 读取 n 和 k
    double maxlen = 0.0; // 最长的绳子长度
    for (int i = 0; i < n; i++)
    {
        cin >> len[i]; // 读取绳子长度
        maxlen = maxlen > len[i] ? maxlen : len[i]; // 将更长的绳长赋值给 maxlen
    }
    // left 是最小的切割后绳长, right 是最长的切割后绳长, mid 是区间 [left, right] 的中点值
    double left = 0.0, right = maxlen, mid;
    while (right - left >= esp) // 直到 right - left 小于指定精度才退出循环
    {
        mid = left + (right - left) / 2; // 防止 right + left 溢出
        if (check(mid))	left = mid;
        else			right = mid;
    }
    // 以下三行代码用于调整输出两位小数
    cout << std::fixed;
    cout.precision(2);
    cout.setf(std::ios_base::showpoint);
    // left 是答案,减去 0.003 是为了修正四舍五入产生的问题
    cout << left - 0.003;
    return 0;
}
  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值