首页 > 其他 > 详细

luogu P1984 [SDOI2008]烧水问题

时间:2017-10-17 09:17:41      阅读:238      评论:0      收藏:0      [点我收藏+]

原题链接:https://www.luogu.org/problem/show?pid=1984

本题的思路其实很好想,那就是对于每一杯未烧开的水,在单独加热它之前,先用之前的杯子与其进行能量均分,直到之前的杯子全部用过一遍,这杯水能达到的温度已经是最高了,想要其烧开就只能加热它了。

然而这样的做法,会有两个问题

1.复杂度:很明显,每一杯水都要遍历之前的各杯,这样的做法复杂度为n^2,而此题n<=50000,可能会超时。

2.精度问题:如果用s来表示每杯水的温度,在与其他杯子进行热量交换时,会有很多/2的操作,而double虽然很好,但是计算次数多了也难免会出现精度问题。

手动计算出每杯水需要加热的温度在100度中占的比例,s1=1,s2=1/2,s3=3/8,s4=5/16,s5=35/128;

似乎没什么规律。但是当用后一项除前一项之后,就得到了这么一个结果

s2/s1=1/2,s3/s2=3/4,s4/s3=5/6,s5/s4=7/8

按照这个规律,s6/s5=9/10,手动模拟计算,确实是此结果,

于是归律便找到了,一次循环即可解决问题,记录(当前的水加热的比例)/(上一杯水加热的比例)的比值,计算出结果,加进答案中即可

 

#include<cstdio>
double n,a=-1,b,ans=1,s=1,t=1;
int main()
{
    scanf("%lf",&n);
    for(int i=2;i<=n;i++)
    {
        a+=2,b+=2;
        s*=(a/b);
        ans+=s;
//        printf("%lf %lf\n",s,ans);
    }
    printf("%.2lf",(ans/n)*420000);
    return 0;
}

 

luogu P1984 [SDOI2008]烧水问题

原文:http://www.cnblogs.com/zeroform/p/7679766.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!