P1009 [NOIP1998 普及组] 阶乘之和(c++)

阶乘之和其实就是每个高精度的乘积加上高精度的加法。如果对里面的代码有些疑惑可以去看我的另外一篇博客。
高精度的计算详解


完整代码:

#include<iostream>
#include<iomanip>
#include<cstring>
#include<sstream>
#include<algorithm>
#include<vector>
using namespace std;
const int Maxn=10000;
ostream&operator<<(ostream &o,int result[]){
    o<<result[result[0]];
    for(int i=result[0]-1;i>0;i--){
        o.width(4);//每次都要输出4位
        o.fill('0');//如果不够4位则要补齐,因为int类型里面的0000会被当作0
        o<<result[i];
    }
    return o;
}
void addition(int num1[],int num2[]){//加法
    int result[Maxn];
    memset(result,0,sizeof(result));
    result[0]=max(num1[0],num2[0]);
    for(int i=1;i<=result[0];i++){
        result[i]+=num1[i]+num2[i];
        if(result[i]>=10000){//则要进行进位
            result[i]-=10000;
            result[i+1]++;//往前进位
        }
    }
    //下面是关键
    if(result[result[0]+1]>0){//类似于9999+1,则会多一位出来,就要判断是否多了一位。
        result[0]++;
    }
    for(int i=0;i<=result[0];i++){//将答案传到num数组中,传出去
        num1[i]=result[i];
    }
}
void multiplication(int num1[],int num2[]){//乘法
    int result[Maxn];
    memset(result,0,sizeof(result));
    result[0]=num1[0]+num2[0]+1;
    for(int i=1;i<=num1[0];i++){
        for(int j=1;j<=num2[0];j++){//就是竖式算法一样,一步步来求
            result[i+j-1]+=num1[i]*num2[j];//减1是为了从第一位开始
            result[i+j]+=result[i+j-1]/10000;//进位
            result[i+j-1]%=10000;
        }
    }
    //下面是关键
    while(result[result[0]]==0&&result[0]>0){//就是把前面多余的0删除
        result[0]--;
    }
    for(int i=0;i<=result[0];i++){//将答案传到num数组中,传出去
        num1[i]=result[i];
    }
}
void factorial_content(int n,int result[]){//一个阶乘
    int num1[Maxn];
    int num2[Maxn];
    memset(num1,0,sizeof(num1));
    memset(num1,0,sizeof(num1));
    num1[0]=1;
    num1[1]=n;
    num2[0]=1;
    for(int i=n-1;i>=2;i--){
        num2[1]=i;
        multiplication(num1,num2);
    }
    for(int i=0;i<=num1[0];i++){
        result[i]=num1[i];
    }
}
void factorial(int n){//各个阶乘的和
    int result[Maxn];
    int finally[Maxn];
    memset(finally,0,sizeof(finally));
    for(int i=n;i>=2;i--){
        memset(result,0,sizeof(result));
        factorial_content(i,result);
        addition(finally,result);
    }
    memset(result,0,sizeof(result));
    result[0]=1;
    result[1]=1;
    addition(finally,result);
    cout<<finally;
}
int main(){
    int n;
    cin>>n;
    factorial(n);
    system("pause");
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值