P1009 [NOIP1998 普及组] 阶乘之和

题目描述

用高精度计算出 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 普及组 第二题

解题思路

首先,需要理解阶乘的概念。阶乘表示一个数从1乘到那个数的过程,例如5! = 5 × 4 × 3 × 2 × 1。

然后,要计算从1!到n!的总和,需要逐个计算每个阶乘的值,并将它们累加起来。

具体步骤如下:

  1. 初始化一个数组来存储最终结果,以及一个数组来存储临时计算的中间结果。
  2. 从1开始循环到n,对于每个数i,计算i!的值。
  3. 对于每个i,初始化一个数组来存储i!的值,并将该数组的第一个元素设置为1(因为任何数的0阶乘都是1)。
  4. 然后,从1循环到i,对于每个数j,将j与i!的当前值相乘,并将结果存储在临时数组中。注意,这里的乘法需要模拟手算乘法的过程,即逐位相乘并处理进位。
  5. 将临时数组中的值复制到i!的数组中,以便进行下一次迭代。
  6. 将i!的值加到最终结果的数组中。同样,这里的加法也需要模拟手算加法的过程,即逐位相加并处理进位。
  7. 循环结束后,最终结果数组中的值就是S的值。

最后,将最终结果数组转换为整数并输出。

代码

#include<stdio.h> 

using namespace std;
int main() //
{  
    int i, A[1005] = {0}, B[1005] = {0}, n, j; // 定义变量i, j, n和两个数组A, B。数组大小设为1005
    scanf("%d", &n); // 从标准输入读取一个整数n  
    A[0] = B[0] = 1; // 初始化数组A和B的第一个元素为1,用于存储阶乘的积  
 
    // 外层循环从2开始到n,计算每个数的阶乘  
    for (i = 2; i <= n; i++) { 
        for (j = 0; j < 1005; j++)
            B[j] = 0;  
          
        B[0] = 1; // 初始化B数组的第一个元素为1,因为任何数的0阶乘都是1  
          
        // 计算i的阶乘,并存储在B数组中  
        for (j = 0; j < i; j++)
            B[j] *= i;  
          
        // 处理B数组中的进位  
        for (j = 0; j < 1005; j++)
            if (B[j] > 9) {  
                B[j + 1] += B[j] / 10;  
                B[j] %= 10;  
            }  
 
        // 将B数组中的值累加到A数组中  
        for (j = 0; j < 1005; j++) // 同上,这里应该将100改为1005  
        {  
            A[j] += B[j];  
            if (A[j] > 9) {  
                A[j + 1] += A[j] / 10;  
                A[j] %= 10;  
            }  
        }  
    }  
 
    // 找到A数组中第一个非零元素的位置  
    for (i = 1005; i >= 0 && A[i] == 0; i--);  
 
    // 从最高位开始打印A数组中的数字,即阶乘和的结果  
    for (j = i; j >= 0; j--) cout<<A[j]<<endl;
 
    return 0; /
}

  • 23
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值