HDU1568 Fibonacci
HDU1568 Fibonacci
題目大意:
對于每一個輸入n(0<=n<=100000000),輸出斐波那契數列第n項的前4個數字。
思路:
附:因為博主比較懶,本文章中幾張公式的圖片來自 以下博客;
PY:看到這道題,第一個想到的是這是一道入門OI的斐波那契數列第n項取模的水題,結果就順手打了一個程序結果發現樣例WA了,然后才發現是第n項的前4個數字。。
這是一道數學題!
首先,我們來推幾個結論。
結論一:
記f(n)為fibonacci數列第n項的值,
那么f(n) = ,這是通項公式,這里不給出證明。 附:對于本題,當n = 0, f(0) = 0。
結論二:
對于正實數n,顯然n = a * 10k ( a <= 10, k為整數) (即科學計數法)。
那么log10( n ) = log10( a * 10k ) = log10( a ) + k ,
因為,a <= 10, 所以,log10( a ) < 1,又因為k為整數,所以,log10( a ) 為 log10( a * 10k ) 的小數部分。
所以log10( a ) = log10( a * 10k ) - [ log10( a * 10k ) ] ? //[ ? ] 為向下取整
結論三:
因為10log10( a ) =? a,所以 a 的前4位有效數字即為a * 10k的前4位。
有了以上三個結論,我們可以開始推式子了:
首先,為了簡化運算,我們對通項公式取對數,可以得到:
?觀察這個式子,我們會發現當n比較大的時候,最后一項幾乎就是0,因為只要結果的前4位,方便計算,我們暫時忽略這一項試試。
所以我們就得到了這個東西:。
對于log10( f(n) ),我們令log10( a ) = log10( f(n) ) - [log10( f(n) )],通過結論二,我們可以發現log10( a ) 就是 log10( (f(n) ) 的小數部分。
接下來, 我們運用結論三,令ans =?10log10( a )? ,如果精度足夠高,那么ans =a,其實說白了就是利用小數的運算使答案的末尾數字直接失去精度而消失,留下答案的前幾位。
這時候我們再回到結論二的開頭,我們會發現 f(n) = ans * 10k,當然,精度不夠,可是f(n)的前幾位都在ans中保留下來了。
此時輸出ans前4位有效數字就能夠得到答案。
?
?
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 using namespace std; 7 int ans[25]; 8 int i,n,m; 9 const double BASE1 = (1.0+sqrt(5.0))/2; 10 double num1,num2; 11 int main(){ 12 ans[0]=0; 13 ans[1]=ans[2]=1; 14 for(i=3;i<=21;i++){ 15 ans[i]=(ans[i-1]+ans[i-2]); 16 } 17 while(scanf("%d",&m)==1){ 18 if(m<=20){ 19 printf("%d\n",ans[m]); 20 }else{ 21 num1=m*log10(BASE1); num2=log10(1/sqrt(5)); 22 num1=num1+num2; 23 num1=num1-floor(num1); 24 num1=pow(10,num1); 25 while(num1<1000) num1*=10; 26 printf("%d\n",(int)num1); 27 } 28 } 29 return 0; 30 }?
?
?
?
?
?
?
?
?
轉載于:https://www.cnblogs.com/linxif2008/p/9539683.html
總結
以上是生活随笔為你收集整理的HDU1568 Fibonacci的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JS - Class继承
- 下一篇: 进阶面向对象——类的成员