Fibonacci
Problem Description
2007年到来了。经过2006年一年的修炼,数学神童zouyu终于把0到100000000的Fibonacci数列
(f[0]=0,f[1]=1;f[i] = f[i-1]+f=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
Author
daringQQ
Source
Happy 2007
Recommend
8600
总结:
以前遇到的斐波那契的问题 是让求第n个斐波那契的后几位数字的,而这次是求前几位数字的,这里就用到了斐波那契的通项公式
1/(根号下5) 与后面的中括号是分离的
取一个大数字的前几位可以采用这样的方法:
例如:123456789
double A = log10(123456789)
= log10(1.23456789*10^8)
= log10(1.23456789) + log10(10^8)
= log10(1.23456789) + 8
log10(1.23456789) 必定是小于1的数
double B = A - floor(A) = log10(1.23456789)
那么10^B 就为 1.23456789,这样,无论取前几位,我们都可以为所欲为,为所欲为了。
接下来我们就可以对斐波那契的通项进行取对数了
[(1-√5)/2]^20 = 0.000066106961351896
[(1-√5)/2]^24 = 0.0000096448756784497
假设A=log10(Fn) = 1.2345678
我们要的是B=0.2345678,所以A数字的小数点后四位一定要保证正确
从第n为24开始,在任何情况下都不会影响小数点后面第四位的数字了,
但是事实上,从第21位开始,小数点后第四位的数字就不再受后面的数字影响了。也就是说,前n《=20 的时候,是不能套用公式的,打表即可。这时候,从第21位斐波那契数开始,位数上升到五位数,这是巧合吗??
log10( (1/√5)*{[(1+√5)/2]^n - [(1-√5)/2]^n} )
=-0.5*log10(5) + n *log10((1+5^0.5)/2)
然后根据前面介绍的方法计算即可
# include <iostream>
# include <stdio.h>
# include <algorithm>
# include <string>
# include <math.h>
using namespace std;
int main(void)
{
long long f1 = 1,f2 = 1;
int f[25];
f[0] = 0,f[1] = 1;
for(int i=2; i<=20; ++i)
f[i] = f[i-1] + f[i-2];
int n;
while(scanf("%d",&n) != EOF)
{
if(n <= 20)
cout << f[n] <<endl;
else
{
double ans = -0.5*log10(5) + n*log10(((1+sqrt(5))/2.0));
ans = ans - floor(ans);
ans = pow(10,ans);
ans *= 1000;
int res = (int )ans;
cout << res <<endl;
}
}
return 0;
}