HDU - 1568 Fibonacci

Fibonacci

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

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

又是斐波那契数列的问题,今天才知道原来斐波那契数列是有通项公式的!

HDU - 1568 Fibonacci_第1张图片

那如何求我们需要的前四项呢?这里要用到对数。

假设给出一个数123456789,那么log10(123456789)=log10(1.23456789*10^8)=log10(1.23456789)+8;
log10(1.23456789)就是log10(123456789)的小数部分。而这个小数部分,就是第n项的斐波那契数。


log10(an)=-0.5*log10(5.0)+((double)n)*log(f)/log(10.0)+log10(1-((1-√5)/(1+√5))^n)其中f=(sqrt(5.0)+1.0)/2.0;
log10(1-((1-√5)/(1+√5))^n)->0
所以可以写成log10(an)=-0.5*log10(5.0)+((double)n)*log(f)/log(10.0);

最后取其小数部分。

#include
#include
int fab[21]={0,1,1};
int main()
{  
    int i,n;  
    for(i=0;i<19;i++)  
    fab[i+2]=fab[i]+fab[i+1];  
    while(scanf("%d",&n)!= EOF)  
    {
        double t;
        if(n<=20)  
        {  
            printf("%d\n",fab[n]);  
            continue;  
        }  
        else  
        {
            t=-0.5*log(5.0)/log(10.0)+((double)n)*log((sqrt(5.0)+1.0)/2.0)/log(10.0); 
            t-=floor(t);
            t=pow(10.0, t);  
            while(t<1000)  
            t*=10;  
            printf("%d\n",(int)t);  
        }  
    }  
    return 0;  
}  


floor函数是向下取整函数。其功能是“向下取整”,或者说“向下舍入”,即取不大于x的最大整数,直接去掉其小数部分。

这道题给我的感觉就是一道数学题,想得出来就很简单,想不出就一点办法都没有。只能说还是要提高自己的知识水平,还是要学习一个。


你可能感兴趣的:(每日AC)