大菲波数
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 22307 Accepted Submission(s): 8010
Problem Description
Fibonacci数列,定义如下:
f(1)=f(2)=1
f(n)=f(n-1)+f(n-2) n>=3。
计算第n项Fibonacci数值。
f(1)=f(2)=1
f(n)=f(n-1)+f(n-2) n>=3。
计算第n项Fibonacci数值。
Input
输入第一行为一个整数N,接下来N行为整数Pi(1<=Pi<=1000)。
Output
输出为N行,每行为对应的f(Pi)。
Sample Input
5
1
2
3
4
5
Sample Output
1
1
2
3
5
【分析】高精度——大斐波那契数
根据f(1)=f(2)=1 f(n)=f(n-1)+f(n-2) n>=3,可知问题的实质即相邻两项的大整数加法。
#include <stdio.h>
#include <string.h>
#define maxn 1010
#define maxlen 225
int N,P;
char num[maxn][maxlen];
char ret[maxlen];
//串逆序
void Reverse(char *s)
{
int i,j;
char temp;
i=0,j=strlen(s)-1;
while(i<=j)
{
temp=s[i];
s[i]=s[j];
s[j]=temp;
i++,j--;
}
}
void getBigFibonacci(int n)
{
int i,j,k;
int len1,len2,lenret;
int sum,acc; //sum-两个数相同数位的和 acc-向高位的进位
//第一项和第二项初始化为1
strcpy(num[1],"1");
strcpy(num[2],"1");
//相邻两项 大整数相加
for(i=3;i<=n;i++)
{
len1=strlen(num[i-2]);
len2=strlen(num[i-1]);
//逆序处理,便于从低位向高位逐位相加
Reverse(num[i-2]);
Reverse(num[i-1]);
j=k=0;
acc=lenret=0;
//两个数的公共部分
while(j<len1 && k<len2)
{
sum=(num[i-2][j]-'0')+(num[i-1][k]-'0')+acc;
ret[lenret++]=sum%10+'0';
acc=sum/10;
j++,k++;
}
//第一个数更长
while(j<len1)
{
sum=(num[i-2][j]-'0')+acc;
ret[lenret++]=sum%10+'0';
acc=sum/10;
j++;
}
//第二个数更长
while(k<len2)
{
sum=(num[i-1][k]-'0')+acc;
ret[lenret++]=sum%10+'0';
acc=sum/10;
k++;
}
//处理进位
while(acc>0)
{
ret[lenret++]=(acc%10)+'0';
acc/=10;
}
ret[lenret]='\0';
//逆序结果为所求
Reverse(ret);
strcpy(num[i],ret);
//恢复
Reverse(num[i-2]);
Reverse(num[i-1]);
}
}
int main()
{
//打表
getBigFibonacci(maxn);
scanf("%d",&N);
while(N--)
{
scanf("%d",&P);
printf("%s\n",num[P]);
}
return 0;
}