大斐波那契数

11 篇文章 0 订阅
2 篇文章 0 订阅

斐波那契数计算公式  :

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;
}

 

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

 

 

Java 代码:

import java.math.*;
import java.util.*;
public class Main{
	public static void main(String[] args){
		Scanner cin = new Scanner(System.in);
		BigInteger[] a;
		a = new BigInteger[2000];
		a[0] = BigInteger.ZERO;
		a[1] = BigInteger.ONE;
		for(int i=2;i<1005;i++)
			a[i] = a[i-1].add(a[i-2]);
		int  n = cin.nextInt();
		while(n-->0){
			int i = cin.nextInt();
			System.out.println(a[i]);
		}
	}
}

 

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

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值