当前位置: 代码迷 >> 综合 >> HDU 1568 Fibonacci(数学 递推式)
  详细解决方案

HDU 1568 Fibonacci(数学 递推式)

热度:46   发布时间:2023-12-12 10:59:54.0

Fibonacci

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)


Problem Description
2007年到来了。经过2006年一年的修炼,数学神童zouyu终于把0到100000000的Fibonacci数列
(f[0]=0,f[1]=1;f[i] = f[i-1]+f[i-2](i>=2))的值全部给背了下来。
接下来,CodeStar决定要考考他,于是每问他一个数字,他就要把答案说出来,不过有的数字太长了。所以规定超过4位的只要说出前4位就可以了,可是CodeStar自己又记不住。于是他决定编写一个程序来测验zouyu说的是否正确。

Input
输入若干数字n(0 <= n <= 100000000),每个数字一行。读到文件尾。

Output
输出f[n]的前4个数字(若不足4个数字,就全部输出)。

Sample Input
  
   
0 1 2 3 4 5 35 36 37 38 39 40

Sample Output
  
   
0 1 1 2 3 5 9227 1493 2415 3908 6324 1023
/************************************************************************/

题意:该题要我们求斐波那契数的前4位

一开始,我还是比较热衷于找规律,毕竟数这么大,不找规律,我能干嘛,但是寻找许久无果。百度了一下斐波那契数列,百科里居然有斐波那契数列的递推式,orz,我知道的太少


关于这个递推式怎么来的,有兴趣可以点个链接看一下

我们稍微将公式转化一下,再取个对数,这样斐波那契数就不会太大了



而我们要取Fibonacci数的前4位,可以通过计算以10为底的对数,原理与HDU 1060 Leftmost Digit是一样的,不妨可以点开看看

另外,需要提及的一点是前20项Fibonacci数需要自己计算,一方面是因为Fibonacci数未满4位,更重要的一点是Fibonacci数较小时,公式的精确度不高

比如第17项Fibonacci应该是1597,但公式求得的是1596;而19项Fibonacci应该是4181,但公式求得的是4180

因此,我们需要先自己计算出Fibonacci数的前19项

现提供一些Fibonacci数以供参考

0
1
1
2
3
5
8
13
21
34
55
89
144
233
377
610
987
1597
2584
4181
6765
10946
17711
28657
46368
75025
121393
196418
317811
514229
832040
1346269
2178309
3524578
5702887
9227465
14930352
24157817
39088169
63245986
102334155
165580141
267914296
433494437
701408733
1134903170
1836311903
2971215073
4807526976
7778742049
12586269025
20365011074
32951280099
53316291173
86267571272
139583862445
225851433717
365435296162
591286729879
956722026041
1548008755920
2504730781961
4052739537881
6557470319842
10610209857723
17167680177565
27777890035288
44945570212853
72723460248141
117669030460994
190392490709135
308061521170129
498454011879264
806515533049393
1304969544928657
2111485077978050
3416454622906707
5527939700884757
8944394323791464
14472334024676221
23416728348467685
37889062373143906
61305790721611591
99194853094755497
160500643816367088
259695496911122585
420196140727489673
679891637638612258
1100087778366101931
1779979416004714189
2880067194370816120

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<stdlib.h>
#include<cmath>
#include<string>
#include<algorithm>
#include<iostream>
#define exp 1e-10
using namespace std;
const int N = 20;
const int inf = 2147483647;
const int mod = 2009;
int f[N];
int main()
{int n,i;double s;f[0]=0,f[1]=1;for(i=2;i<N;i++)//由于接下来利用公式得出来的Fibonacci数不是精确的,越小的数则越不精确,所以前面一些Fibonacci数需要自己算f[i]=f[i-1]+f[i-2];while(~scanf("%d",&n)){if(n<N){printf("%d\n",f[n]);continue;}s=log10(1.0/sqrt(5.0))+n*log10((1+sqrt(5.0))/2);s=s-(int)s;s=pow(10,s);while(s<1000)s*=10;printf("%d\n",(int)s);}return 0;
}
菜鸟成长记