题目描述
用高精度计算出S=1!+2!+3!+…+n!(n≤50)S=1!+2!+3!+…+n! (n≤50)S=1!+2!+3!+…+n!(n≤50)
其中“!”表示阶乘,例如:5!=5×4×3×2×15!=5 \times 4 \times 3 \times 2 \times 15!=5×4×3×2×1。
输入格式
一个正整数NNN。
输出格式
一个正整数SSS,表示计算结果。
输入输出样例
输入 #1
3
输出 #1
9
题意描述
题意很简单就是输入一个数计算从1到这个数的阶乘之和。即1!+2!+3!+.......+n!
解题思路
先算出每个数的阶乘,再将其累加到一个数组上即可。
错误分析
刚开始没有看清题意就开始写了,我就只算了n!,没有进行累加。原来这题是大数加加大数乘,唉,大意了。
下面是代码分为有注释和无注释的,因为有注释的有点乱所以整理一个简洁版
有注释代码
#include<stdio.h>
#include<math.h>
#include<string.h>
int a[100000];
int b[100000];
int c[200000];
int sum[30000];
int Factorial(int m,int n){ //两个字符串相乘函数
for(int i=0;i<m;i++)
for(int j=0;j<n;j++){ //数组相乘
c[i+j]+=a[i]*b[j];
// printf("%d %d %d*\n",a[i],b[j],c[i+j]);
}
for(int i=0;i<m+n-1;i++) //处理进位问题
if(c[i]>=10){
c[i+1]+=c[i]/10;
c[i]%=10;
// printf("%d ",c[i]);
}
// for(int i=0;i<m+n;i++)
// printf("%d ",c[i]);
// printf("******************\n");
int k=m+n; //估计相乘后数组的位数
while(c[k]==0 && k>0) //从后往前找第一个不为0的数的位置,注意至少有一,毕竟0也是一位数
k--;
for(int i=0;i<=k;i++) //为了下次相乘,将相乘的结果保存到b数组中
b[i]=c[i];
for(int i=0;i<=k;i++) //将结果数组清0,不然下次无法计算
c[i]=0;
// printf("%d*\n",k);
return k+1; //返回结果数组的长度
}
int add(int m,int n) //两个字符串累加函数
{
int i=0,j=0;
if(m>=n){ //找到一个比较长的数组长度,进行相加,如果短的没法全部计算,结果就不对了
for(i=0;i<m;i++) //相加
sum[i]+=b[i];
for(i=0;i<m;i++) //处理进位
if(sum[i]>=10){
sum[i+1]+=sum[i]/10;
sum[i]%=10;
}
}
else{
for(i=0;i<n;i++) //相加
sum[i]+=b[i];
for(i=0;i<m;i++) //处理进位
if(sum[i]>=10){
sum[i+1]+=sum[i]/10;
sum[i]%=10;
}
}
if(sum[i+1]!=0) return i+1; //返回相加后的数组的长度。
else return i;
}
int main()
{
int i,j,k,m,n=1,t,x=1,y=1;
scanf("%d",&t);
b[0]=1; //注意相乘的第一位一定为1,不然任何数乘0都为0
for(i=1;i<=t;i++)
{
k=i;j=0;m=0;
while(k){ //计算需要相乘的数字的长度,并逆向存入数组中
m++;
a[j++]=k%10;
k=k/10;
}
// printf("%d %d**\n",m,n);
// for(x=0;x<m;x++) printf("%d",a[x]);printf("\n");
// for(x=0;x<n;x++) printf("%d",b[x]);printf("\n");
x=Factorial(m,x); //调用相乘函数,传递两个数组的长度
y=add(x,y); //调用相加函数,传递两个数组的长度
// printf("%d %d**\n",m,n);
}
// for(i=x-1;i>=0;i--)
// printf("%d",b[i]);
// printf("\n");
// printf("\n");
for(i=y-1;i>=0;i--) //输出结果
printf("%d",sum[i]);
return 0;
}
无注释代码
#include<stdio.h>
#include<math.h>
#include<string.h>
int a[100000],b[100000],c[200000],sum[30000];
int Factorial(int m,int n){
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
c[i+j]+=a[i]*b[j];
for(int i=0;i<m+n-1;i++)
if(c[i]>=10){
c[i+1]+=c[i]/10;
c[i]%=10;
}
int k=m+n;
while(c[k]==0 && k>0)
k--;
for(int i=0;i<=k;i++)
b[i]=c[i];
for(int i=0;i<=k;i++)
c[i]=0;
return k+1;
}
int add(int m,int n)
{
int i=0,j=0;
if(m>=n){
for(i=0;i<m;i++)
sum[i]+=b[i];
for(i=0;i<m;i++)
if(sum[i]>=10){
sum[i+1]+=sum[i]/10;
sum[i]%=10;
}
}
else{
for(i=0;i<n;i++)
sum[i]+=b[i];
for(i=0;i<m;i++)
if(sum[i]>=10){
sum[i+1]+=sum[i]/10;
sum[i]%=10;
}
}
if(sum[i+1]!=0) return i+1;
else return i;
}
int main()
{
int i,j,k,m,n=1,t,x=1,y=1;
scanf("%d",&t);
b[0]=1;
for(i=1;i<=t;i++)
{
k=i;j=0;m=0;
while(k){
m++;
a[j++]=k%10;
k=k/10;
}
x=Factorial(m,x);
y=add(x,y);
}
for(i=y-1;i>=0;i--)
printf("%d",sum[i]);
return 0;
}