POJ-1064 Cable master

本文通过二分查找算法解决了一个给定N根棍子并要求从中切割出K根相同长度棍子的问题。讨论了二分查找区间的选取、精度处理技巧及如何避免使用浮点数以减少误差。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <iostream>
#include <cstdio>
using namespace std;

const int maxn = 10010;
int l[maxn];
int main()
{
    int n, k, Max = 0;
    while(cin >> n >> k)
    {
        for(int i = 0; i < n; i++)
        {
            double x;
            cin >> x;
            l[i] = x * 100;
            Max = max(Max,l[i]);
        }
        int s = 1, h = Max;
        int res = 0;
        while(s <= h)
        {
            int mid = (s + h) * 0.5;
            int count = 0;
            for(int i = 0; i < n; i++)
            {
                int num = l[i]/mid;
                count += num;
            }
            if(count >= k)
            {
                res = max(res,mid);
                s = mid + 1;
            }
            else
                h = mid - 1;
        }
        printf("%.2f\n",res/100.0);
    }
    return 0;
}
题意:给N根棍子,长度分别是 l[0],l[1],l[2],l[3]...之后要切出K根长度相同的棍子。(长度不能小于1cm)
题意:坑。大坑。天坑。总之玩了一天了。不知道有没有玩出什么名堂。希望有所收获。首先 不是所有棍子都必须用到!(一开始取棍子的最小值做h值 然而应该取最大值,短棍子有可能用不上,长棍子用上)。其次 就是精度。一早上都在玩精度,玩不起,玩不来。最后根据精度写的代码连自己都搞不懂怎么回事就过了。最后看到一篇博客,推荐×100化为整数先二分,这样就不用考虑精度问题了。也是感动。
下面是ta的解析:
做法就是二分答案,但是二分的区间有讲究


一开始我认为长度的上限应该是  min { len[i] },即最短的那条线段,后来才想到是错的,应该是max{ len[i] },因为有一点想当然了,认为裁剪线段,就是每条线段都要裁剪,其实不是的,并不是每条线段都要裁剪


好像


4 2


2.00


3.00


4.00


答案是2.00吗?不是的,应该是3.00,虽然3.00大于第一条线段的长度,那么就不要裁剪第1条线段,直接从第2,第3条线段开始裁剪,就能裁剪出2条3.00长度的线段


 


另外,这题可以用浮点数的二分来写,但是基于题目的意思,完全可以转化为整数


因为最后长度不能小于1厘米,而一开始给出的线段也是精确到厘米的,而答案也是要求精确到厘米的,那么为什么我们不一开始就把所有的数据都改成用厘米来表示呢?然后直接用整数来二分就可以避免掉所有精度的问题。所以一开始的二分区间就是[1,max{len[i]}] , 不要从0开始,完全没有比较,因为答案最小要为1


最后一点,也是wa的地方,想了一阵子想明白了


我们二分答案,得到一个长度l,然后用所有线段去除l,看能裁剪出多少条,然后统计条数的总和count


然后就分类


count < m,说明这个长度l太长,筹不够m条,所以要缩点长度l,去左半区间二分


count = m,说明是一个合法的答案,记录,但是这样就可以了吗?可以跳出了吗?不是的,因为要找最大值,所以不能跳出,继续到右半区间二分


count > m , 这是不是一个合法的答案?一开始没想清楚,认为不是合法的答案,其实是的!另外要到右半区间继续二分找一个更大的值


 


下面的这个二分是错误的,就是因为count和m的判断出错


首先count>m的情况是一个合法的答案,最要命的是,可能找不到满足条件的count == m,这能找到count > m


例如


3 5


3.00


3.00


3.00


答案是1.00,当答案是1.00的时候count=9 > 5 , 当答案为2,3的时候,count都无法等于m,根本无法更新答案


因为想歪了一点,虽然题目要筹够m条,如果无法准确筹够m条的时间,只能缩短长度,筹出多余m条线段,因为裁剪多出来的线段,并不规定一定要用完

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值