P1009 [NOIP1998 普及组] 阶乘之和

题目链接 - P1009 [NOIP1998 普及组] 阶乘之和

# [NOIP1998 普及组] 阶乘之和

题目描述
用高精度计算出 \(S = 1! + 2! + 3! + \cdots + n!\)\(n \le 50\))。

其中 ! 表示阶乘,定义为 \(n!=n\times (n-1)\times (n-2)\times \cdots \times 1\)。例如,\(5! = 5 \times 4 \times 3 \times 2 \times 1=120\)

输入格式: 一个正整数 \(n\)
输出格式: 一个正整数 \(S\),表示计算结果。

输入样例输出样例
3
9

数据范围: 对于 \(100 \%\) 的数据,\(1 ≤n ≤ 50\)

分析
涉及知识:高精度
如果直接循环,会出现答案错误,主要是因为数据范围 \(n=50\) 时,数据爆long long,需要使用高精度进行计算。

  • string版本
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10, INF=1<<30;
int A[N],B[N],C[N],la,lb,lc;
// 初始化,同时反转数组
void init(string a,string b) {
    la = a.size(), lb = b.size();
    memset(A, 0, sizeof(A));
    memset(B, 0, sizeof(B));
    memset(C, 0, sizeof(C));
    for(int i=0; i<la; i++) A[i]=a[i]-'0';
    for(int i=0; i<lb; i++) B[i]=b[i]-'0';
    reverse(A, A+la), reverse(B, B+lb);
}
// 高精加高精
string add(string a,string b) {
    init(a,b);
    lc = max(la, lb);
    for(int i=0; i<lc; i++) {
        C[i] = A[i]+B[i]+C[i];
        if(C[i]>9) C[i+1] = C[i]/10, C[i] %= 10;
    }
    while(C[lc]) lc++; //进位
    string c;
    for(int i=lc-1; i>=0; i--) c.append(1, C[i]+'0');
    return c;
}
//高精乘以低精
string mul(string a,int b) {
    memset(A,0,sizeof(A)), la=a.size();
    for(int i=0; i<la; i++) A[i]=a[la-1-i]-'0';
    for(int i=0; i<la; i++) A[i]=A[i]*b;
    for(int i=0; i<la; i++) A[i+1]+=A[i]/10, A[i]%=10;
    while(A[la]) A[la+1]=A[la]/10, A[la]%=10, la++; // 进位
    string c;
    for(int i=la-1; i>=0; i--) c.append(1, A[i]+'0');
    return c;
}
int main() {
    int n; cin>>n;
    string base="1", s="1";
    for(int i=2; i<=n; i++){
        base = mul(base, i);
        s = add(s, base);
    }
    cout<<s<<endl;
    return 0;
}
  • vector版本
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=1e6+10, INF=0x3f3f3f3f;

vector<int> add(vector<int>a,vector<int>b){
    reverse(a.begin(), a.end());
    reverse(b.begin(), b.end());
    vector<int> c; int t=0;
    for(int i=0; i<a.size() || i<b.size(); i++){
        if(i<a.size()) t += a[i];
        if(i<b.size()) t += b[i];
        c.push_back(t%10), t/=10;
    }
    if(t) c.push_back(t);
    reverse(c.begin(), c.end());
    return c;
}
vector<int> mul(vector<int>a,int b){
    reverse(a.begin(), a.end());
    vector<int> c; int t=0;
    for(int i=0; i<a.size()|| t; i++){
        if(i<a.size()) t += a[i]*b;
        c.push_back(t%10), t/=10;
    }
    while(c.size()>1 && c.back()==0) c.pop_back();
    reverse(c.begin(), c.end());
    return c;
}
int main(){
    int n; cin>>n;
    vector<int> base,ans;
    base.push_back(1); ans.push_back(1);
    for(int i=2; i<=n; i++){
        base = mul(base, i);
        ans = add(ans, base);
    }
    for(auto u: ans) cout<<u;
    return 0;
}

完整的高精度:https://www.cnblogs.com/hellohebin/p/16887569.html

posted @ 2023-05-18 16:10  HelloHeBin  阅读(200)  评论(0)    收藏  举报