每日一题 剪绳子(3月27日)

该问题描述了如何在给定数量和长度的绳子中,通过裁剪创造出指定数量的等长绳子,要求最大化这些绳子的长度。解决方案是运用二分查找算法,通过不断调整绳子的分割长度,找到满足条件的最大长度。程序首先找出最长的绳子,然后在最大值和0之间使用二分法,根据能否裁剪出所需数量的绳子来更新搜索范围,直到达到所需的精度。
摘要由CSDN通过智能技术生成

题目描述

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

输入格式

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

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

输出格式

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

样例

输入数据 1

3 4
3 5 4

输出数据 1

2.50

数据范围

1≤N,M≤100000

0<Li​<10的9次方

题解:

用二分法

先求出绳子中最长的一根并与其二分

利用二分法先求中间值,如果用中间值截取的绳长度个数小于m,则中间值较大,将右边的最大值设为中间值,然后继续取最小值和最大值的中间值,如果用中间值截取的绳长度个数大于m,则中间值较小,将左边的最小值设为中间值,然后继续取最小值和最大值的中间值。这样反复取值,最小和最大值将无限靠近正确答案,因为所要求的精度为0.01,可能会出现四舍五入,则要往后精确两位,则为0.0001。

#include<bits/stdc++.h>
using namespace std;
int n,m,maxx,ans;
int l[1000001];
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
     scanf("%d",&l[i]);
     maxx=max(l[i],maxx);//找到最大值
    }
   double z=0,y=maxx;
   while(y-z>0.0001){//两者差距至四位小数点则结束循环
      ans=0;//每次循环从ans都从0开始计算
    double zj=(z+y)/2;//取两者中间值
    for(int i=1;i<=n;i++){
      ans=ans+l[i]/zj;//计算每根绳截取长度能满足中间值并相加
    }
    if(ans<m){//不满足则截取长度过大往左边移动
       y=zj;
    }
    if(ans>=m){//满足则截取长度过小或刚刚好,则往右移动
       z=zj;
    }
   }
    printf("%.2lf",z);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值