hdu1568

Fibonacci(hdu1568)——一道我不知道怎么说的题


Admin
2011年10月4日              名人名言:时间就象海绵里的水一样,只要你愿挤,总还是有的——鲁迅

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



这是道神奇的题,求斐波那契数列的0到第100000000项的前四位,之前做过斐波那契数列的水题,求到63项



能用__int64解决,然则到100000000项的话用数组都邑超时,所以我是一点办法没有,只有进修大牛的解法。



看了下网上的题解,大牛们用的都是下面这个公式,不得不说,数学好才是真的好!o(︶︿︶)o 唉,这公式


是怎么出来的?



以下是大牛的申明:


先看对数的性质,loga(b^c)=c*loga(b),loga(b*c)=loga(b)+loga(c);
假设给出一个数10234432,那么log10(10234432)=log10(1.0234432*10^7)=log10(1.0234432)+7;

log10(1.0234432)就是log10(10234432)的小数项目组.

log10(1.0234432)=0.010063744
10^0.010063744=1.023443198
那么要取几位就很明显了吧~
先取对数(对10取),然后获得成果的小数项目组bit,pow(10.0,bit)今后若是答案还是<1000那么就一向乘10。
重视偶先处理惩罚了0~20项是为了便利处理惩罚~

这题要哄骗到数列的公式:an=(1/√5)
* [((1+√5)/2)^n-((1-√5)/2)^n](n=1,2,3.....)




取完对数




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);
最后取其小数项目组。





固然不是本身想到的,然则还是用c++写了下:


#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;
const double s = (sqrt(5.0)+1.0)/2;
int main()
{
    int n,i;
    double bit;
    int fac[21] = { 0 , 1 };
    for(i = 2; i < 21; i++)
        fac[i] = fac[i-1] + fac [i-2];
    while(cin >> n)
    {
        if(n <= 20) {
            cout << fac[n] << endl;
            continue;
        }
        else{
            bit = -0.5*log(5.0)/log(10.0)+((double)n)*log(s)/log(10.0);//调用公式
            bit = bit - floor(bit); //取小数项目组└(^o^)┘
            bit = pow(10.0,bit);
            while(bit < 1000) //请求四位,所以要将小数点右边的数移到左边直到合适请求
                bit = 10.0 * bit;
            cout << (int)bit << endl;   
        }
    }
    return 0;
}

你可能感兴趣的:(hdu1568)