1. 程式人生 > >luogu P1984 [SDOI2008]燒水問題

luogu P1984 [SDOI2008]燒水問題

span tdi int ret clas 次循環 交換 str spa

原題鏈接: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]燒水問題