题目描述
用高精度计算出 S=1!+2!+3!+⋯+n!S=1!+2!+3!+⋯+n!(n≤50n≤50)。
其中 !
表示阶乘,定义为 n!=n×(n−1)×(n−2)×⋯×1n!=n×(n−1)×(n−2)×⋯×1。例如,5!=5×4×3×2×1=1205!=5×4×3×2×1=120。
输入格式
一个正整数 nn。
输出格式
一个正整数 SS,表示计算结果。
输入输出样例
输入 #1复制
3
输出 #1复制
9
说明/提示
【数据范围】
对于 100%100% 的数据,1≤n≤501≤n≤50。
【其他说明】
注,《深入浅出基础篇》中使用本题作为例题,但是其数据范围只有 n≤20n≤20,使用书中的代码无法通过本题。
如果希望通过本题,请继续学习第八章高精度的知识。
NOIP1998 普及组 第二题
AC代码
#include<stdio.h>
using namespace std;
int main()
{
int i, A[1005] = {0}, B[1005] = {0}, n, j;
// 定义两个数组A和B用于存储高精度数值,初始化为0
// A用于存储最终结果,B用于存储临时阶乘结果
cin >> n; // 输入一个正整数n
A[0] = B[0] = 1; // 初始化A和B数组的第一个元素为1
// 循环计算1!到n!的累加和
for (i = 2; i <= n; i++) {
// 计算i!并存入数组B中
for (j = 0; j < 100; j++)
B[j] *= i; // 将每一位都乘以i
// 处理B数组中的进位
for (j = 0; j < 100; j++)
if (B[j] > 9) {
B[j + 1] += B[j] / 10;
B[j] %= 10;
}
// 将B数组加到A数组上
for (j = 0; j < 100; j++) {
A[j] += B[j];
if (A[j] > 9) {
A[j + 1] += A[j] / 10;
A[j] %= 10;
}
}
}
// 查找A数组的第一个非零元素的位置,从该位置开始输出
for (i = 100; i >= 0 && A[i] == 0; i--);
// 逆序输出数组A中从第一个非零元素开始的所有元素
for (j = i; j >= 0; j--) printf("%d", A[j]);
return 0;
}
解题思路:
1.问题理解:
题目要求计算 S = 1! + 2! + 3! + ... + n! 的值,其中 n 是输入的正整数,且 n ≤ 50。这意味着我们需要计算一系列阶乘的和,直到 n 的阶乘。
2.关键点分析:
* **大数处理**:由于阶乘的结果很快就会变得非常大,超出整型数的表示范围,我们需要使用高精度算法来处理大数。一个常见的方法是将大数表示为字符串,然后逐位进行加法或乘法运算。 * **阶乘计算**:我们需要实现一个函数来计算阶乘。这个函数将整数转化为字符串,然后逐位进行乘法运算。 * **高精度加法**:我们需要实现一个高精度加法函数,用于将两个字符串表示的大数相加。
3.算法流程:
* **初始化**:设置一个字符串变量 s 为 "0",用于存储最终的结果。 * **循环计算阶乘**:从 1 到 n,对每个 i,计算 i 的阶乘并加到 s 上。 * **输出结果**:输出 s,即为所求的 S = 1! + 2! + 3! + ... + n! 的值。