luogu P1984 [SDOI2008]燒水問題
阿新 • • 發佈:2017-10-17
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]燒水問題