题解:洛谷 P1009 [NOIP 1998 普及组] 阶乘之和
【题目来源】
洛谷:P1009 [NOIP 1998 普及组] 阶乘之和 - 洛谷
【题目描述】
用高精度计算出 \(S=1!+2!+3!+\dots+n!(n\le 50)\)。
其中 ! 表示阶乘,定义为 \(n!=n\times(n-1)\times (n-2)\times \dots \times 1\)。例如,\(5!=5\times 4\times 3\times 2\times 1=120\)。
【输入】
一个正整数 \(n\)。
【输出】
一个正整数 \(S\),表示计算结果。
【输入样例】
3
【输出样例】
9
【算法标签】
《洛谷 P1009 阶乘之和》 #数学# #高精度# #NOIP普及组# #1998#
【代码详解】
#include <bits/stdc++.h> // 包含标准库头文件(万能头文件)
using namespace std; // 使用标准命名空间
// 定义全局数组存储阶乘和结果
int a[1010]; // 存储当前阶乘值(倒序存储)
int res[1010]; // 存储阶乘累加和(倒序存储)
/**
* 主函数 - 程序入口
* @return 程序执行状态码(0表示成功)
*/
int main()
{
int n; // 定义变量:计算到n的阶乘和
cin >> n; // 输入n值
// 初始化数组(1! = 1)
a[0] = 1; // 个位存储1
res[0] = 1; // 初始和为1
// 计算2!到n!的阶乘及其累加和
for (int i = 2; i <= n; i++)
{
// 计算i的阶乘(a = a * i)
int carry = 0; // 进位值初始化为0
for (int j = 0; j < 1010; j++)
{
a[j] = carry + a[j] * i; // 当前位乘i加上进位
carry = a[j] / 10; // 计算新的进位
a[j] %= 10; // 保留个位数
}
// 计算1!+2!+...+i!(res += a)
for (int j = 0; j < 1010; j++)
{
res[j] += a[j]; // 逐位相加
res[j+1] += res[j] / 10; // 处理进位
res[j] %= 10; // 保留个位数
}
}
// 计算实际数字长度(去除前导零)
int len = 1010;
while (0 == res[len-1] && len > 1)
{
len--; // 从高位向低位查找第一个非零数字
}
// 倒序输出结果(高位在前)
for (int i = len-1; i >= 0; i--)
{
cout << res[i]; // 输出每一位数字
}
return 0; // 程序正常结束
}
【运行结果】
3
9
浙公网安备 33010602011771号