HDU 1568 Fibonacci

来源:互联网 发布:淘宝卖家店铺装修教程 编辑:程序博客网 时间:2024/05/22 02:31

HDU 1568 Fibonacci

先看对数的性质,loga(bc)=cloga(b),loga(bc)=loga(b)+loga(c);
假设给出一个数10234432,那么log10(10234432)=log10(1.0234432107)=log10(1.0234432)+7;
log10(1.0234432)就是log10(10234432)的小数部分.
log10(1.0234432)=0.010063744
100.010063744=1.023443198
那么要取几位就很明显了吧~
先取对数(对10取),然后得到结果的小数部分bit,pow(10.0,bit)以后如果答案还是<1000那么就一直乘10。
注意偶先处理了0~20项是为了方便处理~
这题要利用到数列的公式:an=(1/5)[((1+5)/2)n((15)/2)n](n=1,2,3.....)

img

取完对数

img

log10(an)=0.5log10(5.0)+((double)n)log(f)/log(10.0)+log10(1((15)/(1+5))n)

其中f=(sqrt(5.0)+1.0)/2.0;
因为log10(1((15)/(1+5))n)趋近于0
所以可以写成log10(an)=0.5log10(5.0)+((double)n)log(f)/log(10.0);
最后取其小数部分。

#include <cstdio>#include <cmath>using namespace std;int n;int f[21]={0,1,1};int main(){    register int i,j;    for (i=2;i<=20;i++) f[i]=f[i-1]+f[i-2];    while (~scanf("%d",&n))    {        if (n<=20)        {            printf("%d\n",f[n]);continue;        }        else         {            double 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;}
原创粉丝点击