1202年,意大利数学家斐波那契出版了他的《算盘全书》,在书中第一次提到了著名的Fibonacci数列,定义如下:
我们最常见的关于Fibonacci数列的就是递归求解,但是当第N项太大时,时间就会很长。下面是递归代码
#include <stdio.h> int fibo(int n) { if(n==0) { return 0; }else if(n==1) { return 1; }else if(n>1) { return fibo(n-1)+fibo(n-2); } } int main() { int n; scanf("%d",&n); printf("%d\n",fibo(n)); return 0; }
/* 思路: size是最大的位数,这里是1000,也就是说最后结果的位数最多只有1000位(好大了); 所以只能用大小为1000的整形数组来存放这么大的数了。(初始化全为0) 又因为Fibonacci数列的当前值,是前两个数之和,所以用两个数组模拟前两个数相加。 如程序中所示,这两个数组分别是a,b;然后大小为1001,是因为多出来的那一位用来 标记当前值一共有多少位,用a[0],b[0]来表示,记住:两个数组相加是从最后一位 (最后一位是个位)开始相加的,也就是为什么a[1001],和b[1001]等于1的原因了。 函数sum(a[],b[]);的作用是将a加到b上。相当于b=b+a;(这里需要用到a[0],因为如果 知道了一共有多少位数,就可以只计算这些位数上的和,而不用计算所有位上的和, 其它不需要的位为0,那样会浪费时间) 函数put(a[]);的作用是把要求的第N项打印出来,因为数字存放在数组中,所以要从最 高位一直打印到最后一位。(这里也需要用到a[0],结果有多少位)。 到底是打印a还是b,与相加的顺序相关 第三项时,把b加到a上,所以要打印a; 第四项时,又把a加到b上,所以要打印b; 如程序中所示,轮流的将a,b加到对方上面,为偶数的时候加到b上,为奇数的时候加到 a上,所以打印的时候也要遵循这个规则。 */ #include<stdio.h> #include<string.h> const int size=1000 ; /* 将a加到b中 */ void sum(int a[],int b[]) { int i,x ; for(i=size;i>size-a[0];i--) { x=a[i]+b[i]; if(x>9) { x%=10 ; b[i-1]++; } b[i]=x ; } if(b[i]==1)//数的长度增一 { b[0]=a[0]+1 ; } else b[0]=a[0]; } void put(int a[]) { int i ; for(i=size-a[0]+1;i<=size;i++) printf("%d",a[i]); } int main() { int a[1001],b[1001]; int n,i ; while(scanf("%d",&n)!=EOF) { memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); a[1000]=1 ; b[1000]=1 ; a[0]=1 ; b[0]=1 ; for(i=3;i<=n;i++) { if(i%2==0)//轮流将a,b加到对方 sum(a,b); else sum(b,a); } if(n%2==0)put(b);//输出最后一次存放结果的数组 else put(a); printf("\n"); } return 0 ; }