HDU 1568 Fibonacci

文章地址:http://henuly.top/?p=677

题目:

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

题目链接

题目需要利用斐波那契数列通项公式(又称“比内公式”)求得,斐波那契通项公式:

F i b ( n ) = 1 5 × [ ( 1 + 5 2 ) n ( 1 5 2 ) n ]

公式具体推导过程看百度百科:

斐波那契数列

由于通项公式在 n 较小时精度较低且 n < 21 F i b ( n ) 也仅仅只有四位数,所以当 n < 21 时利用递推式求解,当 n > 20 时再利用通项公式求解,利用对数求数字前 4 位的方法具体参考

HDU 1060 Leftmost Digit

由于 F i b ( n ) 数据很大,所以先转换通项公式后取对数。

F i b ( n ) = 1 5 × [ ( 1 + 5 2 ) n ( 1 5 2 ) n ]

F i b ( n ) = 1 5 × [ ( 1 + 5 2 ) n ( 1 + 5 2 × 1 5 1 + 5 ) n ]

F i b ( n ) = 1 5 × ( 1 + 5 2 ) n × [ 1 ( 1 5 1 + 5 ) n ]

l o g 10 F i b ( n ) = l o g 10 1 5 × ( 1 + 5 2 ) n × [ 1 ( 1 5 1 + 5 ) n ]

l o g 10 F i b ( n ) l o g 10 1 5 + n × l o g 10 1 + 5 2

AC代码:

#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define mp make_pair
#define lowbit(x) (x&(-x))
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef pair<double,double> PDD;
typedef pair<ll,ll> PLL;
const int INF = 0x3f3f3f3f;
const int maxn = 1e3 + 5;
const int mod = 1e9 + 7;
const double eps = 1e-8;
const double pi = asin(1.0) * 2;
const double e = 2.718281828459;
bool Finish_read;
template<class T>inline void read(T &x) {
    Finish_read = 0;
    x = 0;
    int f = 1;
    char ch = getchar();
    while (!isdigit(ch)) {
        if (ch == '-') {
            f = -1;
        }
        if (ch == EOF) {
            return;
        }
        ch = getchar();
    }
    while (isdigit(ch)) {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    x *= f;
    Finish_read = 1;
};

int main(int argc, char *argv[]) {
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
#endif
    int f[21];
    mem(f, 0);
    f[1] = 1;
    for (int i = 2; i < 21; ++i) {
        f[i] = f[i - 1] + f[i - 2];
    }
    int n;
    while (~scanf("%d", &n)) {
        if (n < 21) {
            printf("%d\n", f[n]);
            continue;
        }
        double ans = log10(1.0 / sqrt(5.0)) + n * log10((1.0 + sqrt(5.0)) / 2.0);
        ans -= ll(ans);
        ans = pow(10, ans);
        while (ans < 1000) {
            ans *= 10;
        }
        printf("%d\n", int(ans));
    }
#ifndef ONLINE_JUDGE
    fclose(stdin);
    fclose(stdout);
    system("gedit out.txt");
#endif
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Tony5t4rk/article/details/81478693