题目
用高精度计算出S=1!+2!+3!+⋯+n!(n≤50)。
其中!
表示阶乘,定义为n!=n×(n−1)×(n−2)×⋯×1。例如5!=5×4×3×2×1=120
输入输出样例
输入
3
输出
9
代码1
这个题目是高精度相加和高精度乘低精度整数的问题,可以采用数组模拟进位的方式解决。
#include<stdio.h>
int main(){
int i,A[1005]={0},B[1005]={0},n,j;//使用数组进行高精度运算,A,B数组初始所有位置都初始化为0
scanf("%d",&n);
A[0]=B[0]=1;//A,B数组的0位置初始化为1
for(int i=2;i<=n;i++){//控制乘数,每一次执行下面的循环以后,B数组存储着当前i值得阶乘,A数组一次将前面计算得阶乘累加储存,同时两个数组不断进位
for(int j=0;j<100;j++){//相当于100位可以扩充
B[j]*=i;
}
for(int j=0;j<100;j++){//进位
if(B[j]>9){
B[j+1]+=B[j]/10;
B[j]=B[j]%10;
}
}
for(int j=0;j<100;j++){
A[j]+=B[j];//累加前面得阶乘
if(A[j]>9){//进位
A[j+1]+=A[j]/10;
A[j]%=10;
}
}
}
for (i=100;i>=0&&A[i]==0;i--);//去掉前导0
for (j=i;j>=0;j--) printf("%d", A[j]);//输出
return 0;
}
代码2
这个问题同样采用封装大整数类并重载运算符的方式来解决。封装结构体的一个好处是使得代码模块化,容易调试并且使用简洁干净,不易在接口上使用出错。
#include<iostream>
#include<cstring>
#include<algorithm>
#define maxn 100
using namespace std;
struct Bigint{
int len,a[maxn];
Bigint(int x=0){
memset(a,0,sizeof(a));
for(len=1;x;len++){
a[len]=x%10;
x/=10;
}
len--;
}
int &operator[](int i){
return a[i];
}
void flatten(int L){
len=L;
for(int i=1;i<=len;i++){
a[i+1]+=a[i]/10;
a[i]%=10;
}
for(;!a[len];){
len--;
}
}
void print(){
for(int i=max(len,1);i>=1;i--){
cout<<a[i];
}
}
};
Bigint operator + (Bigint a,Bigint b){
Bigint c;
int len=max(a.len,b.len);
for(int i=1;i<=len;i++){
c[i]+=a[i]+b[i];
}
c.flatten(len+1);
return c;
}
Bigint operator * (Bigint a,int b){
Bigint c;
int len=a.len;
for(int i=1;i<=len;i++){
c[i]=a[i]*b;
}
c.flatten(len+11);
return c;
}
int main(){
Bigint ans(0),fac(1);
int m;
cin>>m;
for(int i=1;i<=m;i++){
fac=fac*i;
ans=ans+fac;
}
ans.print();
}