Hdu 3117 Fibonacci Numbers

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=3117

解题思路:

很显然费波纳数的后四位存在周期,通过测试可以发现后四位的周期为15000,所以后四位可以打表得出,

前四位是参考了别人的思路才做出来的。

因为费波纳数f[n] = 1/sqrt(5)(((1+sqrt(5))/2)^n+((1-sqrt(5))/2)^n).

很显然当n非常大的时候(1-sqrt(5))/2)^n非常的小以至于可以忽略,假设F[n]可以表示成 t * 10^k(t是一个小数),那么对于F[n]取对数log10,答案就为log10 t + K,此时很明显log10 t<1,于是我们去除整数部分,就得到了log10 t ,再用pow(10,log10 t)我们就还原回了t。将t×1000就得到了F[n]的前四位。

题目实现:

#include<stdio.h>
#include<math.h>
#define aa (sqrt(5.0)+1.0)/2  
int fib_h[15000],Fib[40] = {0,1,1,2,3,5,8,13},n;
int main()
{
	fib_h[0] = 0 ;fib_h[1] = 1;
	//费波那数后四位
	for(int i = 2; i <= 14999; i++)
	{
		fib_h[i] = (fib_h[i-1] + fib_h[i-2])%10000;
	}
	for(i = 7; i < 40; i++)
		Fib[i] = Fib[i-1] + Fib[i-2];
	while(scanf("%d",&n) != EOF)
	{
		if(n < 40)
			printf("%d\n",Fib[n]);
		else
		{
			double	ans = -0.5*(log10(5.0))+n*log10(aa);
			ans-=(int)ans; 
			 ans=pow(10.0,ans);  
            while(ans<1000)  
                ans*=10;  
            printf("%d...",(int)ans);   
            printf("%4.4d\n",fib_h[n%15000]);  
		}
	}
	return 0;
}


 

posted @ 2012-09-05 10:24  一生挚爱  阅读(137)  评论(0编辑  收藏  举报