下面是一个阶乘相加的程序,但是当n>12此程序就会内存不足,导致溢出。
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,m=0;
cin >>n;
for(int i=1;i<=n;i++){
int a=1;//重置
for(int j=1;j<=i;j++){
a=a*j;
}
m=m+a;
}
cout<<m<<endl;
return 0;
}
重点是以下代码,c 代表进位,f[0]为最低位(跟现实不太一样,从低位开始,因为要进位)。
int s=f[j]*i+c;
f[j]=s%10;
c=s/10;
上面代码就是模拟手算过程,过程示意如下
举一个例子:
54391+90
1 | 9 | 3 | 4 | 5 |
0 | 9 | 0 | 0 | 0 |
1 | 18 | 3 | 4 | 5 |
1 | 8 | 4 | 4 | 5 |
f[2]=18%10=8,c =18/10=1
可得到54481
以下是一个高精度的阶乘程序,结合上面可以更好理解此代码。
#include<bits/stdc++.h>
using namespace std;
int main(){
const int N=3000;
int f[N] ={0};int m[N]={0};//格式化
int i,j,n;
cin>>n;
f[0]=1;
m[0]=1;
for( i=2;i <=n;i++){//i为每次乘数
int c=0;//进位
for( j=0;j<N;j++){//阶乘
int s=f[j]*i+c;
f[j]=s%10;
c=s/10;
}
for(j =0;j<N;j++){//阶乘之和
m[j] += f[j];
m[j+1] += m[j]/10;
m[j] %= 10;
}
}
for( j= N-1;j>=0;j--) if(f[j]) break;//把数前面的0全部去除,比如000110,输出110
for( i =j; i>=0;i--) cout<<m[i];//因为是从低位到高位,所以倒序输出
cout<<endl;
return 0;
}
- [P1009 [NOIP1998 普及组] 阶乘之和](https://www.luogu.com.cn/problem/P1009)