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;
}

浙公网安备 33010602011771号