当前位置: 首页 > news >正文

P1009 [NOIP 1998 普及组] 阶乘之和

P1009 [NOIP 1998 普及组] 阶乘之和

题目描述

用高精度计算出 \(S = 1! + 2! + 3! + \cdots + n!\)\(n \le 50\))。

其中 ! 表示阶乘,定义为 \(n!=n\times (n-1)\times (n-2)\times \cdots \times 1\)。例如,\(5! = 5 \times 4 \times 3 \times 2 \times 1=120\)

输入格式

一个正整数 \(n\)

输出格式

一个正整数 \(S\),表示计算结果。

输入输出样例 #1

输入 #1

3

输出 #1

9

说明/提示

【数据范围】

对于 \(100 \%\) 的数据,\(1 \le n \le 50\)

【其他说明】

注,《深入浅出基础篇》中使用本题作为例题,但是其数据范围只有 \(n \le 20\),使用书中的代码无法通过本题。

如果希望通过本题,请继续学习第八章高精度的知识。


这道题在类型上属于 高精度乘法 + 高精度加法的综合应用

题目大意

计算 \(S = 1! + 2! + 3! + \dots + n!\),其中 \(n \le 50\),阶乘结果远超 64 位整数范围,必须手写高精度。

特征 说明
题型分类 高精度加法 + 高精度乘法的综合应用
核心知识点 ① 高精度乘低精度(阶乘用) ② 高精度加高精度(求和用)
与 P1303 的区别 P1303 是高精度 × 高精度;本题阶乘只需高精度 × 低精度(乘数 ≤ 50),逻辑更简单

因为乘数 i(2~50)始终是普通整数,所以乘法时逐位乘 int 加进位即可,不用嵌套双循环,这也是本题与 P1601 加法模版结合的最佳切入点。

解决思路

  1. 拆成两个步骤

    • 高精度乘低精度:计算当前 i 的阶乘 fact = fact × i
    • 高精度加高精度:sum = sum + fact
  2. 数组倒序存储(低位在前):

    • a[0] 是个位,a[1] 是十位,以此类推。
  3. 具体流程

    • 初始化 a[]sum[] 均为 1(即 1!)。
    • i = 2n
      • 调用高精度乘低精度,把 i 乘进 a[]
      • 调用高精度加高精度,把 a[] 累加到 sum[]
    • 去掉前导零,逆序输出 sum[]

方法一:基础高精度(数组模拟,通俗易懂)

#include <iostream>
using namespace std;const int MAXN = 2000;  // 50! 约 65 位,2000 很安全
int a[MAXN];            // 存放当前阶乘
int sum[MAXN];          // 存放最终和// 高精度 × 低精度
void mul(int a[], int x) {int carry = 0;for (int i = 0; i < MAXN; ++i) {carry += a[i] * x;a[i] = carry % 10;carry /= 10;}
}// 高精度 + 高精度
void add(int sum[], int a[]) {int carry = 0;for (int i = 0; i < MAXN; ++i) {carry += sum[i] + a[i];sum[i] = carry % 10;carry /= 10;}
}int main() {int n;cin >> n;a[0] = 1;sum[0] = 1;for (int i = 2; i <= n; ++i) {mul(a, i);add(sum, a);}// 逆序输出int p = MAXN - 1;while (p > 0 && sum[p] == 0) --p;for (int i = p; i >= 0; --i)cout << sum[i];cout << endl;return 0;
}

方法二:vector 版本(更安全,方便复用)

#include <iostream>
#include <vector>
using namespace std;// 高精度 × 低精度
vector<int> mul(const vector<int>& A, int b) {vector<int> C;int carry = 0;for (size_t i = 0; i < A.size(); ++i) {carry += A[i] * b;C.push_back(carry % 10);carry /= 10;}while (carry) {C.push_back(carry % 10);carry /= 10;}return C;
}// 高精度 + 高精度
vector<int> add(const vector<int>& A, const vector<int>& B) {vector<int> C;int carry = 0;size_t i = 0;while (i < A.size() || i < B.size() || carry) {int x = (i < A.size() ? A[i] : 0);int y = (i < B.size() ? B[i] : 0);carry += x + y;C.push_back(carry % 10);carry /= 10;++i;}return C;
}int main() {int n;cin >> n;vector<int> fact = {1};   // 当前阶乘vector<int> sum  = {1};   // 累加和for (int i = 2; i <= n; ++i) {fact = mul(fact, i);sum  = add(sum, fact);}// 逆序输出for (int i = sum.size() - 1; i >= 0; --i)cout << sum[i];cout << endl;return 0;
}

Python 版本

Python 自带大整数,直接硬算就能 AC。但手写结构可以帮助理解思路。

def mul(A, x):C = []carry = 0for a in A:carry += a * xC.append(carry % 10)carry //= 10while carry:C.append(carry % 10)carry //= 10return Cdef add(A, B):C = []i = carry = 0while i < len(A) or i < len(B) or carry:x = A[i] if i < len(A) else 0y = B[i] if i < len(B) else 0carry += x + yC.append(carry % 10)carry //= 10i += 1return Cn = int(input())
fact = [1]
s = [1]
for i in range(2, n + 1):fact = mul(fact, i)s = add(s, fact)
print(''.join(str(x) for x in reversed(s)))

总结

内容 说明
题目类型 高精度加法 + 高精度乘法的综合应用
乘法特征 高精度 × 低精度(乘数 ≤ 50),比 P1303 的大数相乘简单
加法特征 与 P1601 逻辑完全一致,只多一个累加循环
核心优化 边乘边进位,处理好进位链
学习价值 高精度四则运算的综合性练习
http://www.jsqmd.com/news/791855/

相关文章:

  • QGC源码探秘:从PlanView到SimpleItemEditor的航点编辑链路剖析
  • 让我们创建一个自定义的数学计算工具。
  • 109.YOLOv8底层逻辑拆解:TaskAlignedAssigner正负样本分配+推理流程数学化
  • 26年湛江一中高一期中考试第19题
  • Taotoken多模型聚合平台为开发者提供稳定高效的模型调用服务
  • GRT 深度解剖:单芯片雷达基础模型的全栈技术图谱
  • JoyCon-Driver:在Windows上使用Switch手柄的终极完整指南
  • 告别网盘限速:LinkSwift网盘直链下载助手使用指南
  • 如何查询昂首资本ASIC监管证明真假(5分钟自查版) - CFDMKting
  • 终极解决方案:如何彻底解锁网易云音乐灰色歌曲
  • Java学习第四周博客
  • 别再手动拷贝文件了!HBuilder云打包APK的两种高效工作流对比(本地嵌入 vs. 远程URL)
  • QMC音频转换工具终极指南:快速免费解锁加密音乐文件
  • Blue Archive自动脚本:Mumu模拟器检测问题终极解决指南
  • 深入剖析`ReentrantReadWriteLock`源码——虚拟线程时代机遇、挑战与演进
  • AcFun视频离线保存:3个关键场景下的智能下载解决方案
  • 111.YOLOv1手动复现完整代码,从网络定义到NMS后处理
  • Python: Condition Variable Pattern
  • LinkSwift:八大网盘直链下载终极解决方案,告别客户端束缚
  • 2025届毕业生推荐的六大降AI率神器解析与推荐
  • LinkSwift:免费网盘直链下载的完整解决方案
  • WPS-Zotero插件终极指南:5步实现科研写作效率翻倍的完整教程
  • 从LTE到5G NR:同步信号设计演进全解析,SSB为何是性能提升的关键
  • 2026淮北干洗店大测评,权威排名帮你省心选优店! - GrowthUME
  • DLSS Swapper深度解析:游戏性能优化利器实战指南
  • 5步优化DXVK配置:告别游戏卡顿与兼容性问题
  • 5.6 springboot项目配置
  • 抖音评论数据采集神器:3分钟零代码获取完整评论数据
  • NPYViewer终极指南:如何5分钟快速可视化NumPy数组数据
  • 长期使用Taotoken平台对于模型选型决策效率的实际影响