hdu1568(斐波那契数列通项公式)

题目链接:hdu1568

一道数学题。。。被数学完虐了。。。。

先看对数的性质,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,

要求该数的前4位,则将1.023443198*1000即可。

因此,pow(10.0,x的小数部分)即可方便求出x的前几位。

求一数的前4位的对数方法可以表述为:

double x,temp;
while(scanf("%lf",&x)!=EOF)
{
    temp=log10(x);
    temp=temp-floor(temp); //floor(temp)函数求出小于temp的最大整数
    temp=pow(10.0,temp);
    while(temp<1000)
    temp*=10;
    printf("%d\n",(int)temp);
}

本题采用斐波那契数列通项公式

F(n)=(1/√5)*[((1+√5)/2)^n-((1-√5)/2)^n](n=1,2,3.....)
改变通项的形式
F(n)=(1/√5)*[((1+√5)/2)^n-((1-√5)/2)^n](n=1,2,3.....)
=(1/√5)*[((1+√5)/2)^n*(1-((1-√5)/(1+√5))^n)](n=1,23.....)
即F(n)的各项可以由以上通项公式求得,而不是采用迭代。
对变化后的通项取对数,则得下式:
log10(F(n))=-0.5*log10(5.0)+((double)n)*log(f)/log(10.0)+log10(1-((1-√5)/(1+√5))^n)
其中第三部分非常小,当n很大时趋近于0,可以忽略掉。
因此,采用下式即可:
temp=-0.5*log(5.0)/log(10.0)+((double)n)*log(s)/log(10.0);

转自:点击链接

代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <cmath>
using namespace std;
int main()
{
    int i,n;
    int f[21]={0,1};
    for(i = 2; i < 21; i ++)
    f[i] = f[i-1] + f[i-2];
    double s = (sqrt(5.0)+1.0)/2.0;
    while(~scanf("%d",&n))
    {
        if(n < 21)
        {
            printf("%d\n",f[n]);
            continue;
        }
        double ans = -0.5*log(5.0)/log(10.0)+((double)n)*log(s)/log(10.0);
        ans -= floor(ans);
        ans = pow(10.0,ans);
        while(ans < 1000)
        ans *= 10;
        printf("%d\n",(int)ans);
    }
    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值