zoukankan      html  css  js  c++  java
  • 【洛谷】P1009 阶乘之和——高精度算法

    题目描述

    用高精度计算出S = 1! + 2! + 3! + … + n!  ( n ≤  50 ) 123… n≤ 5)

    其中“!”表示阶乘,例如:5! = 5 × 4 × 3 × 2 × 1

    输入格式

    一个正整数NN。

    输出格式

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

    输入输出样例

    输入 #
    3
    输出 #
    9
     
    这道题的数据50的阶乘超过了c语言所有数据类型的范围,也就是无法用long long类型,或者unsigned long long来解决
    因此这里需要使用【高精度算法】,通俗点说明就是用数据模拟加减乘除
     
    通过查询,学会了该算法的基本形式
    (【入门】高精度算法——lazy-sheep :https://blog.csdn.net/zsjzliziyang/article/details/82050337 )
     
    接下来就是应用到该题中了
    这道题需要运用到高精度的乘法和加法
    高精度算法的基本操作是通过把一个[字符数组]的数据转换成对应的[整数数组]
    便可以通过字符数组的strlen()方法来获取数组长度
    而在这道题中需要进行手动维护
     
    先上AC代码
    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    int res[100010], p[100010];///res存放结果, p存放阶乘结果
    int len0, len1;///len0维护res长度,len1维护p长度
    void Plus()
    {
        int len = max(len0, len1);
        for(int i = 0; i < len; i++){
            res[i] = res[i] + p[i];
            res[i+1] += res[i]/10;
            res[i] = res[i]%10;
            if(res[i] && i >= len0)len0++;
        }
    }
    
    void Multi(int a)
    {
    
        for(int i = 0; i < len1; i++)p[i] *= a;
        for(int i = 0; i < len1; i++){
            p[i+1] += p[i]/10;
            p[i] = p[i]%10;
            if(p[i+1] && i+1 >= len1)len1++;
        }
    }
    int main()
    {
        int n;
        while(scanf("%d", &n) != EOF)
        {
            memset(res, 0, sizeof(res));
            memset(p, 0, sizeof(p));
            res[0] = 0;
            len0 = len1 = p[0] = 1;
            for(int i = 1; i <= n; i++)
            {
                Multi(i);
                Plus();
            }
            for(int i = len0-1; i >= 0; i--)printf("%d", res[i]);
            printf("
    ");
        }
    }
    

     

    在乘法中,需要维护的是每次阶乘结果p的长度len1

    每当进位的时候就需要对len1加1

    void Multi(int a)
    {
    
        for(int i = 0; i < len1; i++)p[i] *= a;
        for(int i = 0; i < len1; i++){
            p[i+1] += p[i]/10;
            p[i] = p[i]%10;
            if(p[i+1] && i+1 >= len1)len1++;
        }
    }
    

      

    在加法中,需要注意阶乘的结果p得到的数组长度都会比res长
    同样每当进位的时候就需要对长度len0加1
    void Plus()
    {
        int len = max(len0, len1);
        for(int i = 0; i < len; i++){
            res[i] = res[i] + p[i];
            res[i+1] += res[i]/10;
            res[i] = res[i]%10;
            if(res[i] && i >= len0)len0++;
        }
    }
    

      

     
  • 相关阅读:
    右键菜单:锁到任务栏丢失 修复
    检测到鼠标时自动禁用触摸板 (注:仅适用于个别笔记本)
    清除右键菜单CMD入口
    VBS编辑字段
    VBS创建数据表
    VBS创建数据库
    QTP操作论坛回复编辑框----webelement
    数字排序
    对应键盘的ASCII码(备忘)
    将字符串打乱输出
  • 原文地址:https://www.cnblogs.com/leftstan/p/13805844.html
Copyright © 2011-2022 走看看