2072: 切网线

题目描述

仙境的居民们决定举办一场程序设计区域赛。裁判委员会完全由自愿组成,他们承诺要组织一次史上最公正的比赛。他们决定将选手的电脑用星形拓扑结构连接在一起,即将它们全部连到一个单一的中心服务器。为了组织这个完全公正的比赛,裁判委员会主席提出要将所有选手的电脑等距离地围绕在服务器周围放置。
为购买网线,裁判委员会联系了当地的一个网络解决方案提供商,要求能够提供一定数量的等长网线。裁判委员会希望网线越长越好,这样选手们之间的距离可以尽可能远一些。 该公司的网线主管承接了这个任务。他知道库存中每条网线的长度(精确到厘米),并且只要告诉他所需的网线长度(精确到厘米),他都能够完成对网线的切割工作。但是,这次,所需的网线长度并不知道,这让网线主管不知所措。
你需要编写一个程序,帮助网线主管确定一个最长的网线长度,并且按此长度对库存中的网线进行切割,能够得到指定数量的网线。

输入

第一行包含两个整数N和K,以单个空格隔开。N(1 ≤ N ≤ 10000)是库存中的网线数,K(1 ≤ K ≤ 10000)是需要的网线数量。
接下来N行,每行一个数,为库存中每条网线的长度(单位:米)。所有网线的长度至少1m,至多100km。输入中的所有长度都精确到厘米,即保留到小数点后两位。

输出

网线主管能够从库存的网线中切出指定数量的网线的最长长度(单位:米)。必须精确到厘米,即保留到小数点后两位。若无法得到长度至少为1cm的指定数量的网线,则必须输出“0.00”(不包含引号)。

样例输入 

4 11
8.02
7.43
4.57
5.39

样例输出 

2.00
#include<stdio.h>
#include<algorithm>
 
int N, K;//库存网线数,需要网线数
int a[10000] = { 0 };//保存库存网线数据
int ans=0,*max;//记录答案,库存网线最大长度
double temp;//接收库存网线数据的工具
 
int cnt(int l)//计算库存网线可以分得长度为l的网线多少根
{
    int sum = 0;
    for (int i = 0; i < N; i++)
    {
        sum += a[i] / l;
    }
    return sum;
}
 
int main()
{
    scanf("%d%d", &N, &K);
    for (int i = 0; i < N; i++)
    {
        scanf("%lf", &temp);
        a[i] = 100 * temp;//数据整型化处理
    }
    //找最大值,需注意,该函数返回的是一迭代器
    max = std::max_element(a, a + N);
    //左开右开写法,区间为(0,*max+1)
    int left = 0, right = *max + 1,mid,sum;
    while (left + 1 != right)
    {   //本来就是要找网线可分割最大长度,不妨向上取整
        mid = left + ((right - left + 1) >> 1);
        sum = cnt(mid);
        if (sum >= K) {//满足题意
            ans = mid;//记录答案
            left = mid;//继续往右搜索
        }
        else if (sum < K) {//不满足题意,网线太长
            right = mid;//往左搜索
        }
    }
    //虽然连1cm都满足不了时ans=0,0/100.0在“%.2f”控制下可输出0.00
    if (ans < 1) {//但去掉特判就不能AC了,不知道为什么
        printf("0.00");//可能是因为题目要求输出字符串?
    }
    else printf("%.2f", ans / 100.0);
    return 0;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值