Hdu 3117【斐波那契】

来源:互联网 发布:哪个漫画软件日漫最全 编辑:程序博客网 时间:2024/06/01 13:31

原文链接:http://blog.csdn.net/q3498233/article/details/5336783

/*Fibonacci Numbers Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other)Total Submission(s) : 0   Accepted Submission(s) : 0Font: Times New Roman | Verdana | Georgia Font Size: ← →Problem DescriptionThe Fibonacci sequence is the sequence of numbers such that every element is equal to the sum of the two previous elements, except for the first two elements f0 and f1 which are respectively zero and one.What is the numerical value of the nth Fibonacci number? InputFor each test case, a line will contain an integer i between 0 and 108 inclusively, for which you must compute the ith Fibonacci number fi. Fibonacci numbers get large pretty quickly, so whenever the answer has more than 8 digits, output only the first and last 4 digits of the  answer, separating the two parts with an ellipsis (“...”). There is no special way to denote the end of the of the input, simply stop when the standard input terminates (after the EOF).Sample Input0123453536373839406465Sample Output0112359227465149303522415781739088169632459861023...41551061...77231716...7565SourceIPCP 2005 Northern Preliminary for Northeast North-America --------------------------------------------------------------------------------*/#include<stdio.h>#include<math.h>int last[15010] = {0,1,1}, fib[40] = {0,1,1};int main(){int i, j, k, n;for(i = 3; i < 15001; i++)//the last  4 digit's circle is 15000last[i] = (last[i-1] + last[i-2]) % 10000;for(i = 3; i < 40; i++)    // 8 digit's numfib[i] = fib[i-1] + fib[i-2];while(scanf("%d", &n) != EOF){if(n < 40)printf("%d\n", fib[n]);else{double ans;ans = (-0.5)*(log10(5.0)) + (double)n * (log10((1.0+sqrt(5))/2.0));ans -= (int) ans;ans = pow(10.0, ans);//10^answhile(ans < 1000)ans *= 10.0;printf("%d...%4.4d\n", (int)ans, last[n%15000]);//%4.4d  when digits are not longer than 4 fill 0 before}}return 0;}

题意:求斐波那契数列,给出一个0<i<10^8,输出第i个数,当长度大于8位时,仅输首四位和末四位。

思路:首先对于长度不大于8位的直接求出答案,当长度大于8位时,分别求末四位和首四位,其中末四位以15000为周期出现循环,直接用数组保存,难点在于求首四位。

我们要搬出Fibonacci的通项公式——
f(n)=1/sqrt(5)(((1+sqrt(5))/2)^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]的前四位。

具体实现的时候Log10 F[n]约等于((1+sqrt(5))/2)^n/sqrt(5),这里我们把((1-sqrt(5))/2)^n这一项忽略了,因为当N>=40时,这个数已经小的可以忽略。于是log10 F[n]就可以化简成log10 1/sqrt(5) + n*log10 (1+sqrt(5))/2,接着就是去除整数部分,并用pow还原小数,再求出前四位。

注意:输出格式要注意,就是末四位有可能小于1000,输出时要保持四位数,在数字前面补0。

0 0
原创粉丝点击