http://acm.hdu.edu.cn/showproblem.php?pid=1568
先说n较大的情况:
这里会用到斐波那契的通项公式:
取对数可得,
结果设为logg,其中第三项很小且趋向于0,所以省略。将logg舍去整数部分后再作为10的指数,可以得到f(n)不断除以10得到的小于10的形式,设为ans。这题要求前4位,只要把ans再乘到大于等于1000后取整数部分即可。
而n较小时(如当n<=20时)为了避免省略了第三项的误差,就直接用用递推公式求。
#include <iostream>
#include <stdio.h>
#include <cmath>
using namespace std;
const double tmp = (1.0+sqrt(5.0))/2.0;
int f(int x)
{
if(x==0)
return 0;
if(x==1)
return 1;
return f(x-1)+f(x-2);
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
if(n<=20)
printf("%d\n",f(n));
else
{
double logg = -0.5*log10(5.0) + n*log10(tmp);
logg -= floor(logg);
double ans = pow(10.0,logg);
while(ans<1000)
ans *= 10;
printf("%d\n",(int)ans);
}
}
return 0;
}