求阶乘的和

GitHub跳转原题关系图返回列表

题目描述

给定正整数 nn(1<n<121 < n < 12),求不大于 nn 的正整数的阶乘的和,即 S=1!+2!+⋯+n!S = 1! + 2! + \cdots + n!,输出 SS。

输入一行一个正整数 nn;输出一行阶乘的和。例如输入 5,输出 153(1!+2!+3!+4!+5!=1531!+2!+3!+4!+5! = 153)。

思路

利用递推关系 i!=i×(i−1)!i! = i \times (i-1)!,维护当前阶乘值 f,初始为 11(即 1!1!),从 11 到 nn 每轮先乘 ii 再累加到答案。n<12n < 12 时 n!≤11!≈4×107n! \le 11! \approx 4 \times 10^7,用 long long 存答案即可,总复杂度 O(n)O(n)。

参考代码

Python 版:

python
#!/usr/bin/env python3
# Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
# rbook: -> https://rbook.roj.ac.cn  https://rbook2.roj.ac.cn
# rainboy的学习导航网站: https://idx.roj.ac.cn
# create_at: 2026-09-29 18:16
# update_at: 2026-10-04 09:30

import sys
from itertools import accumulate


def solve() -> None:
    data = iter(map(int, sys.stdin.buffer.read().split()))
    n = next(data)
    # 阶乘递推:f_i = i * f_{i-1},前缀和:s_i = s_{i-1} + f_i
    facts = accumulate(range(1, n + 1), lambda f, i: f * i, initial=1)  # 初始 f_0 = 1
    print(sum(facts) - 1)  # 去掉多余的 0! = 1


if __name__ == "__main__":
    solve()

C++ 版(同一算法):

cpp
/**
 * Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
 * rbook: -> https://rbook.roj.ac.cn  https://rbook2.roj.ac.cn
 * rainboy的学习导航网站: https://idx.roj.ac.cn
 * create_at: 2026-10-05 00:48
 * update_at: 2026-10-05 00:48
 */

#include <cstdio>

typedef long long ll;

ll n;   // 题目给出的上限
ll f;   // f 当前维护 i! 的值
ll ans; // 答案:1! + 2! + ... + n!

int main() {
    scanf("%lld", &n);
    f = 1;   // 1! = 1,从这里开始递推
    ans = 0;
    for (ll i = 1; i <= n; i++) {
        f = f * i; // 递推:i! = i * (i-1)!
        ans = ans + f;
    }
    printf("%lld\n", ans);
    return 0;
}