HDU - 1568 Fibonacci(思维)

http://acm.hdu.edu.cn/showproblem.php?pid=1568

题意: 就是斐波那契数,但是有的非常大,去前4位

思路:本来以为要用数组去算大数,单数看了大神的代码,茅塞顿开

首先,要用到这个公式,这个是斐波那契的通项公式,当趋近与∞时,(\frac{1 - sqrt{5}}{2})^n可以忽略,

所以这时,t = log_{10}{F(n)} = log_{10}{(\frac{1}{\sqrt{5}})} * log_{10}{((\frac{1 + \sqrt{5}}{2})^n)}

k = \frac{1}{\sqrt{5}} * (\frac{1 + \sqrt{5}}{2})^n

这是 t有整数部分,有小数部分,整数部分代表的是位数,小数部分代表的是log10(k)的值,而且t = log10(Fn)

所以当 t -= (int)t 后,代表的是就是log10(k)的值,这是对于t进行pow(10, t)得到的就是fn的值,不过这时的值是小数形式,下面求前4位就很简单了

调试代码

        double k = pow(2, 5);
        double t = log10(k);
        double t1 = n * log10(2);
        double t2 = t - (int)t;
        double t3 = pow(10, t2);
        printf("%lf, %lf, %lf, %lf, %lf\n", k , t, t1, t2, t3);

AC代码

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <math.h>
using namespace std;
const int maxn = 1e5 + 5;
int a[maxn];
int main(int argc, const char * argv[]) {
    int n;
    while(scanf("%d", &n) != EOF){
        double k = (1. + sqrt(5.)) / 2.;
        a[0] = 0;
        a[1] = 1;
        for (int i = 2; i <= 22; i ++)
            a[i] = a[i - 1] + a[i - 2];
        if(n <= 20)
            printf("%d\n", a[n]);
        else {
            double t = log10(1. / sqrt(5.)) + n * log10(k);
            t -= (int)(t); // 整数部位是位数,小数部位是log10(FN=n)的值
            t = pow(10, t);
            while(t < 1000) {
                t *= 10;
            }
            printf("%d\n", (int)t);
        }

    }
    return 0;
}
扫描二维码关注公众号,回复: 2773281 查看本文章

猜你喜欢

转载自blog.csdn.net/henu_jizhideqingwa/article/details/81478262