题解:洛谷 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
posted @ 2026-02-16 15:14  团爸讲算法  阅读(1)  评论(0)    收藏  举报