大斐波那契数

斐波那契数计算公式  :

f(n)=f(n-1)+f(n-2)        (n>=3)

f(1)=1

f(2)=1

对于 n 比较小的情况下,下边的程序就可以实现这个功能

#include<cstdio>
#define ll long long 
const int n=100;
int main() 
{
	ll a[n];
	a[2]=1;a[1]=1;
	for(int i=3;i<n;i++)
		a[i]=a[i-1]+a[i-2];
	for(int i=1;i<n;i++)
		printf("%d   %lld\n",i,a[i]);
	return 0;
}

结果如下:



请注意,当 n = 92的时候,结果还是正确的,但是 n 一旦超过92.long long 类型就无法储存这么大的数了



溢出了,所以我们需要寻找新的方法来计算 n 比较大的时候那些情况的斐波那契数

我们需要用到模拟的思想,开一个比较大的二维数组来储存每一个斐波那契数,再让它们的每一位相加最后得出的结果就是答案了,详情请看代码,

/*
  大斐波那契数 

*/
#include<cstdio>
#include<cstring>
#define ll long long
const int MAXN=1e4+3;
const int c=10000;
ll a[MAXN][MAXN];
int main()
{
	int n;
	while(~scanf("%d",&n))
	{
		a[1][0]=1;a[2][0]=1;//初始化 第一个数和第二个数 
		int dight=0;//斐波那契数的 位数 
		int temp=0;//储存进位
		for(int i=3;i<=n;i++)	//从3算到N
		{
			temp=0;//进位每次计算都要初始化为0
			for(int j=0;j<=dight;j++)
			{
				a[i][j]=a[i-1][j]+a[i-2][j]+temp;
				temp=a[i][j]/10;
				a[i][j]%=10;
			 } 
			if(temp)//如果有进位的话 
			{
				dight++;//位数加一 
				a[i][dight]=temp;//给最高位赋值 
			}
		 } 
		for(int i=dight;i>=0;i--)//逆序输出这个数组 
			printf("%lld",a[n][i]);//n代表是第n个斐波那契数,i是这个数的第i位 
		printf("\n");			
	}
	return 0;
}
应该可以把这个代码优化一下,以便于计算更大的数
/*
  大斐波那契数 

*/

//这段代码让每一个a[i][j]的值都是9位 
#include<cstdio>
#include<cstring>
#define ll long long
const int MAXN=1e4+3;
const int c=1e9;
ll a[MAXN][MAXN];
int main()
{
	int n;
	while(~scanf("%d",&n))
	{
		a[1][0]=1;a[2][0]=1;
		int temp=0;
		int d=0;
		for(int i=3;i<=n;i++)
		{
			temp=0;
			for(int j=0;j<=d;j++)
			{
				a[i][j]=a[i-1][j]+a[i-2][j]+temp;
				temp=a[i][j]/c;
				a[i][j]%=c;
			}
			if(temp)
			{
				d++;
				a[i][d]=temp;
			}	
		}	
		printf("%lld",a[n][d]);
		for(int i=d-1;i>=0;i--)
			printf("%010lld",a[n][i]);
		printf("\n");
	}
	return 0;
}
可以来这里联系一下: HDU_1715

AC代码如下:

#include<cstdio>
#include<cstring>
const int MAXN=1004;
int a[MAXN][MAXN];
int main()
{
	int t,n;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d",&n);
		a[1][0]=1,a[2][0]=1;
		int d=0;
		int temp=0;
		for(int i=3;i<=n;i++)
		{
			temp=0;
			for(int j=0;j<=d;j++)
			{
				a[i][j]=a[i-1][j]+a[i-2][j]+temp;
				temp=a[i][j]/10;
				a[i][j]%=10;
			}
			if(temp)
			{
				d++;
				a[i][d]=temp;
			}
		}
		for(int i=d;i>=0;i--)
			printf("%d",a[n][i]);
		printf("\n");
	}
	return 0;
}

大斐波那契数和大数阶乘的思想是一样的,不同的是大数阶乘只用了一维数组,比这个要简单一些




在下实力有限,如有错误请您指出,谢谢

猜你喜欢

转载自blog.csdn.net/hpuer_random/article/details/80057587