您的位置:首页 > 其它

hdu 1568 Fibonacci(fibonacci通项+对数性质)

2015-03-25 22:16 267 查看

Fibonacci

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

Total Submission(s): 3721 Accepted Submission(s): 1710



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
的前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

题目大意:求取给定序位的斐波那契数的前四位

题目分析:

求取斐波那契有三种方法,线性递推,矩阵快速幂,和通项公式;

因为要求的是前四位,所以快速幂没办法做到

而数据量又直接导致线性不能达到,那么只能利用通项公式求取

但是直接记录的话会超各种,甚至高精度

所以我们要利用对数的性质,取单纯记录位上的数字

也就是对f(n)取对数,那么小数部分便能完全记录需要的位数

只需要取到前四位即可,所以乘以1000即可,预处理前20位打表特判

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cmath>

using namespace std;

double get ( int n )
{
    return n*log10((1.0+sqrt(5.0))/2.0) - 0.5*log10(5.0);
}

int n;
int f[20];

int main ( )
{
    f[0] = 0 , f[1] = f[2] = 1;
    for ( int i = 3 ; i <= 20 ; i++ )
        f[i] = f[i-1] + f[i-2];
    while ( ~scanf ( "%d" , &n ) )
    {
        if ( n <= 20 )
            printf ( "%d\n" , f
 );
        else
        {
            double ans = get ( n );
            ans -= floor ( ans );
            ans = pow ( 10 , ans );
            printf ( "%d\n" , (int)(ans*1000) );
        }
    }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: