/*
斐波那契数列通项公式
fib[n]=(1/√5) * [((1+√5)/2)^n-((1-√5)/2)^n](n=1,2,3.....)
或者写成[(1+√5)/2]^n /√5 - [(1-√5)/2]^n /√5 【√5表示根号5】
// 为什么有两种写法,因为我试过不同的编译器,和不同的OJ,有时候是第一个式子正确,有时候是第二个式子正确
fib[87]到fib[91]的数都大于1e18
*/
/*
eg:
输出斐波那契数前4位数(数据范围n<100000000...忘了反正很大)
*/
int fib[22];
int main()
{
double num;
int n,f,i;
fib[0]=0;
fib[1]=1;
for(i=2;i<=20;i++)
fib[i]=fib[i-1]+fib[i-2];
while(~scanf("%d",&n))
{
if(n<=20)//前20个数小于10000可以直接输出。
{
cout<<fib[n]<<endl;
continue;
}
num=n*(log10((1+sqrt(5.0))/2.0))-log10(sqrt(5.0));
/*
*这里对通项公式两边同时取对数.由于n较大时((1-√5)/2)^n很小可以忽略,所以这里对公式进行了简化。
*/
num-=floor(num);
/*
*取小数部分。由于个位数可以看成10的整数次方(如10^5.987=10^5*10^0.987)所以把个位数忽略也不影响结果的钱4位数字。
*/
num=pow(10,num);//得到一个小数(与对应的斐波那契数差(10^x)倍)
while(num<1000)
num*=10;
f=num;//消除小数部分得到前4位数
printf("%d\n",f);
}
return 0;
}
斐波那契数列通项公式
于 2016-09-16 15:39:17 首次发布