码迷,mamicode.com
首页 > 其他好文 > 详细

【自用】POJ1064 Cable master 且来说说卡精度的心得

时间:2015-03-17 22:00:10      阅读:208      评论:0      收藏:0      [点我收藏+]

标签:poj1064   卡精度   自用   二分   二分查找   

广告:

#include <stdio.h>
int main()
{
    puts("转载请注明出处[vmurder]谢谢");
    puts("网址:blog.csdn.net/vmurder/article/details/44347241");
}

题意:

多组数据,n个小棒,分成m段,最长多长?
不能短于0.01,如果分不出来,输出”0.00”

题解:

满足单调性,来二分吧。

心得:

来,我们看着代码说话。

判无解的处理

首先最多能分多少段开了long long。
long long maxd,m;
然后处理的时候因为精度损失,所以加了eps
maxd+=(int)(a[i]*100.0+eps);

eps

因为处理两位,所以至少应该开4位吧,然后因为其它的一些东西,所以我最终开了八位
#define eps 1e-8

避免出现无解而误判的情况

右边界的设置减了eps,事实上这里并不需要进行此项判断。
double l=0.01,r=mx-eps,mid;

对于答案的输出

我们发现因为精度损失,所以导致末尾舍去的时候会出现误差,这个时候应该灵活的减去或者增加2
printf("%.2lf\n",l-0.00499);
啊这里有点瞎了,貌似应该是+0.005,但是过了。

至于为什么是0.00499呢?因为还有精度损失,所以还需要加减eps。

选择语言

正规考试并不会有这个问题,但是平时评测的时候,尤其POJ!
每改一份代码,你可能需要C++和G++都交一遍。

代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 10100
#define eps 1e-8
using namespace std;

int n;
long long maxd,m;
double a[N],mx;
bool check(double mid)
{
    int ret=0,i;
    for(i=1;i<=n;i++)ret+=(int)(a[i]/mid+eps);
    return ret>=m;
}
int main()
{
//  freopen("test.in","r",stdin);
    int i,j,k;
    while(scanf("%d%I64d",&n,&m)!=EOF)
    {
        maxd=0,mx=0.0; 
        for(i=1;i<=n;i++)
        {
            scanf("%lf",&a[i]);
            mx=max(mx,a[i]);
            maxd+=(int)(a[i]*100.0+eps);
        }
        if(maxd<m)
        {
            puts("0.00");
            continue;
        }
        double l=0.01,r=mx-eps,mid;
        while(r-l>eps)
        {
            mid=(l+r)/2.0;
            if(check(mid))l=mid;
            else r=mid;
        }
        printf("%.2lf\n",l-0.00499);
    }
    return 0;
}

【自用】POJ1064 Cable master 且来说说卡精度的心得

标签:poj1064   卡精度   自用   二分   二分查找   

原文地址:http://blog.csdn.net/vmurder/article/details/44347241

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!