poj 1064 二分

挑战p140
链接:http://poj.org/problem?id=1064
这题不难,二分很容易想到,就是精度感觉好难受··· 一直WA
思路:二分枚举最长的长度,判断当前的这个假定的长度是否可以切割出k条绳子。如果可以说明可以将这个长度在变长点,如果不行,将其变小再试。
要小心的就是最后区间左右端的选择。个人觉得如果可行将mid付给low,low 应该是表示可以割出的,最后应该输出low。但是这样会WA。
照理来说左右端应该没有太多区别,最后区间的大小已经足够小了,可能还要看具体题目吧。
**学习:**floor()函数,取不大于传入值的最大整数。如floor(3.14) = 3。此题用此函数来消除最后的误差,由于保留两位小数,则可以用floor(high*100)/100。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define M 10009
#define INF 0x7f7f7f7f
int n,m;
double a[M];
bool judge(double x)
{
    int sum = 0;
    for(int i = 0;i < n;i++)
        sum += a[i]/x;
    return sum >= m;
}
void slove(double temp)
{
    double low = 0.0,high = temp;
    double mid;
    while(high-low > 1e-6)
    {
        mid = (high+low)/2;
        if(!judge(mid))
            high = mid;
        else
            low = mid;
    }
    printf("%.2f\n",floor(high*100)/100);
}
int main()
{
    while(scanf("%d %d",&n,&m)==2)
    {
        double max1 = -INF;
        for(int i = 0;i < n;i++)
        {
            scanf("%lf",&a[i]);
            max1 = max(max1,a[i]);
        }
        slove(max1);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值