【洛谷】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++;
    }
}

  

 
原文地址:https://www.cnblogs.com/leftstan/p/13805844.html