HDU3117——Fibonacci Numbers

The 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?

Input

For each test case, a line will contain an integer i between 0 and 10 8 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 Input

0
1
2
3
4
5
35
36
37
38
39
40
64
65

Sample Output

0
1
1
2
3
5
9227465
14930352
24157817
39088169
63245986
1023...4155
1061...7723
1716...7565
解这道题我们先来了解一下斐波那契数列
通项公式F(n)=(1/√5)*{[(1+√5)/2]^n - [(1-√5)/2]^n}
 Fibonacci 数列的一个性质:
 * 尾数循环:
 *    斐波那契数列的个位数:一个60步的循环 11235,83145,94370,77415,61785.38190,99875,27965,16730,33695,49325,72910…
 *    进一步,斐波那契数列的最后两位数是一个300步的循环,最后三位数是一个1500步的循环,
 *    最后四位数是一个15000步的循环,最后五位数是一个150000步的循环。
若是直接套公式将结果存入double中也会造成溢出。。。所以需要化简
但是式子有些复杂又不好化简,好在只需要求前4位,对精度要求不是太高,所以把(1-√5)/2这一项去掉不影响结果
令x=log10(1/sqrt(5)),y=log10((1+sqrt(5))/2);
那么log10(fn)=x+n*y,  fn=10^(x+n*y)
代码如下(已AC)
 1 #include<iostream>
 2 #include<math.h>
 3 using namespace std;
 4 
 5 const double x=log10(1.0/sqrt(5.0));
 6 
 7 const double y=log10((1.0+sqrt(5.0))/2.0); //.0绝对不能省 
 8 int main()
 9 {
10     int n,i,a[50]={0,1,1};//a是存放菲波那切数列前39个 
11 
12     int b[15001]={0,1};//b是存放斐波那契数的后四位 
13 
14     double res;//求前四位 
15 
16     //最小的斐波那契9位数是第40个,所以n<40直接输出结果 
17         //当n>=40时要分成前四位和后四位输出
18     for(i=3;i<40;i++)
19 
20     a[i]=a[i-1]+a[i-2];
21 
22     for(i=2;i<15001;i++)
23     {
24             b[i]=b[i-1]+b[i-2];
25 
26             if(b[i]>=10000)
27 
28             b[i]%=10000;
29     }
30 
31     while(scanf("%d",&n)!=EOF)
32     {
33         if(n<40)
34         {
35             cout<<a[n]<<endl;
36 
37             continue;
38         }
39                  res=x+n*y;
40 
41                  res-=(int)res;//只保留小数位
42 
43          res=pow(10,res)*1000; //乘出四位整数位+小数位的形式
44 
45               printf("%d...%0.4d\n",(int)res,b[n%15000]);
46                //(int)是强制类型转换,防止前四位之后的出现 
47          
48     }
49     return 0;
50 
51 }
View Code

 

 

 

posted @ 2020-04-08 21:26  Tina_xiao  阅读(224)  评论(0)    收藏  举报