斐波那契数列(公式)
http://acm.hdu.edu.cn/showproblem.php?pid=1568
Fibonacci
Time Limit: 1000/1000 MS (Java/Others)Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3947Accepted Submission(s): 1817
Problem Description
2007年到來了。經過2006年一年的修煉,數學神童zouyu終于把0到100000000的Fibonacci數列
(f[0]=0,f[1]=1;f[i] = f[i-1]+f[i-2](i>=2))的值全部給背了下來。
接下來,CodeStar決定要考考他,于是每問他一個數字,他就要把答案說出來,不過有的數字太長了。所以規定超過4位的只要說出前4位就可以了,可是CodeStar自己又記不住。于是他決定編寫一個程序來測驗zouyu說的是否正確。
Input
輸入若干數字n(0 <= n <= 100000000),每個數字一行。讀到文件尾。
Output
輸出f[n]的前4個數字(若不足4個數字,就全部輸出)。
Sample Input
0
1
2
3
4
5
35
36
37
38
39
40
Sample Output
0
1
1
2
3
5
9227
1493
2415
3908
6324
1023
要取前四位,用對數的方法log(fn)的小數部分是log(原數的科學計數法中前半部分),故10的這個小數次方就是這個原數的科學計數法中前半部分
求大數前幾位的方法
當一個數非常大時,如何求出其前幾位呢?
如果是給定一個特定的數,當然可以逐步取出每一位即可。如
a得個位,a/10得百位,a/10/10得千位。
但是,當求x^y的前幾位時怎么辦呢?若x,y都非常大,則顯然很難解決:也許可以用大數乘法,暴力求解,結果自然是既占內存,又耗時間。
還有,此題斐波拉契數列的前幾位,顯然求出每個斐波拉契數是不現實的。因此,可以采用取對數的方法來解決。
先看對數的性質,loga(b^c)=c*loga(b),loga(b*c)=loga(b)+loga(c);假設給出一個數10234432,那么log10(10234432)=log10(1.0234432*10^7)=log10(1.0234432)+7
log10(1.0234432)就是log10(10234432)的小數部分.
log10(1.0234432)=0.010063744
10^0.010063744=1.023443198,
要求該數的前4位,則將1.023443198*1000即可。
因此,pow(10.0,x的小數部分)即可方便求出x的前幾位。
求一數的前4位的對數方法可以表述為:
double x,temp;
while(scanf("%lf",&x)!=EOF)
{
temp=log(x)/log(10.0);
temp=temp-floor(temp); //floor(temp)函數求出小于temp的最大整數
temp=pow(10.0,temp);
while(temp<1000)
temp*=10;
//printf("%.0lf
",temp); //采用浮點表達法時會四舍五入
printf("%d
",(int)temp);//此處不需四舍五入,直接舍棄后面的位
}
}
下面給出斐波那契數列通項公式:
但是這個題要是直接套公式還是會超時,所以我們將通項公式左右取對數,化簡得
log10(F(n))=-0.5*log10(5.0)+((double)n)*log(s)/log(10.0)+log10(1-((1-√5)/(1+√5))^n)
s =(1+sqrt(5.0))/2.0;
<提取的公因式s,然后將后面化成兩式相乘的形式>
注意:其中第三部分非常小,當n很大時趨近于0,可以忽略掉。
下面給出代碼
1 #include<cstdio>
2 #include<cmath>
3 using namespace std;
4 /*
5 double f (int n )
6 {
7 return (1.0/sqrt(5.0))*(pow(((1.0+sqrt(5.0))/2),n)-pow( ((1.0-sqrt(5.0))/2),n ) );
8 } 這樣處理以后還是會車超*/
9 int ff(int n )
10 {
11 if(n==0) return 0;
12 if(n==1) return 1;
13 return ff(n-1)+ff(n-2);
14 }
15 int main()
16 {
17 int n;
18 while(~scanf("%d",&n))
19 {
20 //printf("%d ",(int)f(n));
21 if(n>=21)
22 {
23 //double temp = log(f(1.0*n))/log(10.0);//計算的時候還是會超
24 double s = (1+sqrt(5.0))/2.0;
25 double temp = -0.5*log(5.0)/log(10.0)+((double)n)*log(s)/log(10.0);
26 temp = temp - floor(temp);
27 temp = pow(10.0,temp);
28 while(temp<1000.0)
29 {
30 temp*=10.0;
31 }
32 printf("%d
",(int)temp);
33 }
34 else
35 printf("%d
",ff(n));
36 }
37 return 0;
38 }
總結
以上是生活随笔為你收集整理的斐波那契数列(公式)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 电信宽带怎么设置路由器电信如何让网络连路
- 下一篇: 怎么清理路由器缓存数据艾泰路由器如何清理