#include <stdio.h>
#include <string.h>
#define N 256
// 反转字符串
void reverseStr(char *str) {
int len = strlen(str);
for (int i = 0; i < len / 2; i++) { // 奇数就除了中间的数字不反转,偶数就都反转一遍
char temp = str[i];
str[i] = str[len - i - 1];
str[len - i - 1] = temp;
}
}
// 高精度加法函数
void highPrecisionAdd(char *num1, char *num2, char *result) {
int len1 = strlen(num1);
int len2 = strlen(num2);
int carry = 0; // 进位
int i = 0, j = 0, k = 0;
// 反转两个数字字符串,以便从最低位开始相加
reverseStr(num1);
reverseStr(num2);
// 逐位相加
while (i < len1 || j < len2 || carry) {
int sum = carry;
if (i < len1) {
sum += num1[i] - '0';
i++;
}
if (j < len2) {
sum += num2[j] - '0';
j++;
}
result[k++] = (sum % 10) + '0'; // 计算当前位的值并转为字符
carry = sum / 10; // 计算进位
}
result[k] = '\0'; // 添加字符串结束符
reverseStr(num1);
reverseStr(num2);
// 反转结果字符串,恢复正确的顺序
reverseStr(result);
}
// 高精度乘法函数
void highPrecisionMultiply(char* num1, char* num2, char* result) {
int len1 = strlen(num1);
int len2 = strlen(num2);
int lenResult = len1 + len2;
int idxResult;
// 初始化结果数组
for (int i = 0; i < lenResult; i++) {
result[i] = '0';
}
result[lenResult] = '\0';
// 反转两个数字字符串
reverseStr(num1);
reverseStr(num2);
// 逐位相乘
for (int i = 0; i < len1; i++) {
for (int j = 0; j < len2; j++) {
int mul = (num1[i] - '0') * (num2[j] - '0');
int sum = mul + (result[i + j] - '0');
result[i + j] = (sum % 10) + '0';
result[i + j + 1] += sum / 10;
}
}
// 移除前导零
while (result[lenResult - 1] == '0' && lenResult > 1) {
lenResult--;
}
result[lenResult] = '\0';
reverseStr(num1);
reverseStr(num2);
// 反转结果字符串
reverseStr(result);
}
int main() {
int n = 0;
scanf_s("%d", &n);
char jiecheng[N] = {'1'};
jiecheng[0] = '1';
char sum[N] = {'0'};
for(int i =1;i<=n;i++)
{
char tmp[N];
char j[20];
sprintf(j, "%d", i);
highPrecisionMultiply(j, jiecheng, tmp);//计算阶乘
strcpy(jiecheng, tmp); // 更新阶乘值
highPrecisionAdd(sum, jiecheng, tmp); // 累加阶乘和
strcpy(sum, tmp); // 更新阶乘和
}
printf("%s", sum);
return 0;
}