#include<iostream>
#include<stdio.h>
#include<string.h>
#define maxn 2000
#define maxm 2001
using namespace std;
int fact[51][maxm];
int temp[maxm];
//阶乘之和
/*本题需要注意的地方:
1。BigInt * int ,小的int不必转换为BigInt。直接每一位相乘,再来调整进位
2.先算完再思考进位的事情。
3.本题不知道BigInt 的长度。那么就直接从最大的位置开始往低位遍历。
遍历到不是0的部分就说明到有意义的部分了。
关于一些骗分数的方法:
1。刚开始做题的时候,把maxn开的大一点,把极限输入,得到最大需要多少位。
比如这一道题目就不需要把maxn设为2000,200就够了
2.得到正确代码之后,得到所有的解,直接打表。、
*/
void mult(int c) {
for (int i = 1; i <= maxn; i++) {
fact[c][i] = fact[c - 1][i] * c;
}
for (int i = 1; i <= maxn; i++) {
if (fact[c][i] >= 10) {
int carry = fact[c][i] / 10;
fact[c][i] %= 10;
fact[c][i + 1] += carry;
}
}
}
void add(int i) {
for (int j = 1; j <= maxn; j++) {
temp[j] += fact[i][j];
}
for (int j = 1; j <= maxn; j++) {
if (temp[j] >= 10) {
int carry = temp[j] / 10;
temp[j] %= 10;
temp[j + 1] += carry;
}
}
}
int main() {
int n;
scanf("%d", &n);
memset(fact, 0, sizeof(fact));
memset(temp, 0, sizeof(temp));
fact[0][1] = 1;
for (int i = 1; i <= n; i++) {
mult(i);
add(i);
}
int frontzero = 1;
for (int i = maxn; i >= 1; i--) {
if (temp[i] != 0) {
frontzero = 0;
}
if (frontzero == 0) {
printf("%d", temp[i]);
}
}
return 0;
}
更加优秀的解法:
#include<iostream>
#include<stdio.h>
#include<string.h>
#define maxn 2000
using namespace std;
int main() {
int fact[maxn + 2];
int add[maxn + 2];
int n;
memset(fact, 0, sizeof(fact));
memset(add, 0, sizeof(add));
// scanf("%d", &n);
scanf("%d", &n);
fact[0] = 1;
int product=1,sum,carrymul=0,carryplu=0;//carry of multiply,carry of plus
int j;//j是位数
int l=1;
for (int i = 1; i <= n; i++) {
for (j = 0; j < maxn; j++) {
/*注意顺序:
1.计算当前这一个位,记得要带上进位
2.得新的这一个位置上面的数(%10)
3.得到carry*/
product = fact[j] * i+carrymul;//现在carrymul是上一次计算的
fact[j] = product % 10;
carrymul = product / 10;//现在carrymul是这一次计算得到的。顺序很重要。
sum = add[j] + fact[j] + carryplu;
add[j] = sum % 10;
carryplu = sum / 10;
if (fact[j + 1] == 0 && carrymul == 0
&& add[j + 1] == 0 && carryplu == 0
&& j + 1 >= l) {
break;
}
}
l = j;
}
int frontzero = 1;
for (int i = maxn - 1; i >= 0; i--) {
if (add[i] != 0) {
frontzero = 0;
}
if (!frontzero) {
printf("%d", add[i]);
}
}
return 0;
}
j+1>=l的理解,见高精度计算 模版