1250Hat'sFibonacci
大数加法提高
题目链接http://acm.hdu.edu.cn/showproblem.php?pid=1250
Problem Description
A Fibonacci sequence iscalculated by adding the previous two members the sequence, with the first twomembers being both 1.
F(1) = 1, F(2) = 1, F(3) = 1,F(4) = 1, F(n>4) = F(n - 1) + F(n-2) + F(n-3) +F(n-4)
Your task is to take a number as input, and print that Fibonacci number.
Inp
Each line will contain anintegers. Process to end of file.
Output
For each case, output theresult in a line.
Sample Input
100
Sample Output
4203968145672990846840663646
Note:
No generated Fibonacci numberin excess of 2005 digits will be in the test data, ie. F(20) = 66526 has 5digits.
题目意思就是一个数等于他前面四个数的和,然而题目并不是这个水的。这个数可以达到2005位,一下子就变成大数问题了。还记不记得上次那个大数阶乘是怎么做的。用一个数组来存,数组中的一个元素存储几个位的数,来简化大数问题,至于要存储几位这个就随意了。可根据题目要求来选择有时可以简化代码(就如同上次的N!题目取5位一存)。这题一个数组元素存储5位来做。
1,先要定义一个两维数组,a[10000][405];
405; 因为有2005位除以5就可以等到了,然后开大一点就就是405;
至于那100000;就是试出来的,直接定大一点就可以了。
2;然而来介绍一下那种方法,感觉大数问题基本上都可以用到这种方法。定义一个数组,用这个数组里面的元素来存几位数字,现在来说这题,这题与上次说的有些不同,它是先将一个数组的元素全部都加完,然后再用一个循环来处理进位问题。
3,哦,还没说,这题是要用到打表的方法,打表的范围就是刚开始那二维数组的下标。
4;这题还有最后一个问题就是输出问题吧?
颠倒过来输出,但我们这是打表的方法,怎么找到我们要输出的下标。我们刚开始初始化数组是0。只需要找到数组元素不为0的下标,以后的就是我们要输出的数组元素啊。输出跟上次N!的输出一样的。
摆代码了,
#include<stdio.h>
inta[10000][408]={0};//五位一存
//408是因为有2005位除以5就可以等到了,然后开大一点就OK了
int main()
{
int i, j, jws, n;
a[1][0] = 1;
a[2][0] = 1;
a[3][0] = 1;
a[4][0] = 1;
for(i = 5; i < 10000 ; i++){
for(j = 0; j < 408; j++)
a[i][j] =a[i-1][j]+a[i-2][j]+a[i-3][j]+a[i-4][j];
for(j = 0; j < 408; j++){//不能像大数阶乘那样放在里面一边算一边进位;这里要单独进位;
if(a[i][j] > 99999){
a[i][j+1]+= a[i][j]/100000;
a[i][j]= a[i][j]%100000;
}
}
}
while(scanf("%d",&n) !=EOF){
for(j = 407; j >= 0; j--){
if(a[n][j] != 0){
break;
}
}
printf("%d",a[n][j]);
for(j = j-1; j >= 0; j--){
printf("%05d",a[n][j]);//与大数阶乘一类型的题目;
}
printf("\n");
}
return 0 ;
}