题目传送门
是否要用高精?
虽然50看上去不是很大,但是它的阶乘之和却达到了31035053229546199656252032972759319953190362094566672920420940313(三百一十万零三千五百零五亿三千二百二十九万五千四百六十一亿九千九百六十五万六千二百五十二亿零三百二十九万七千二百七十五亿九千三百一十九万九千五百三十一亿九千零三十六万二千零九十四亿五千六百六十六万七千二百九十二亿零四百二十万零九千四百零三*一百+十三)
所以——一定要用高精!!!
50分
思路
如果你不会高精,用unsigned long long ,能得50分(long long也能得50分)
代码:
#include<iostream>
using namespace std;
unsigned long long a,ans=0;
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
a=1;
for(int j=1;j<=i;j++){
a*=j;
}
ans+=a;
}
cout<<ans;
return 0;
}
100分
思路
高精加(阶乘相加时用)+高精乘(计算阶乘时用)模拟,计算的ans要用string类型。
代码
高精加
string g_jia(string a,string b){
int lena=a.length(),lenb=b.length();
if(lena<lenb){
for(int i=1;i<=lenb-lena;i++)a='0'+a;
}else{
for(int i=1;i<=lena-lenb;i++)b='0'+b;
}lena=a.length(),lenb=b.length();
int lens=lena;
int jw=0,cnt=0;
string ans;
for(int i=lens-1;i>=0;i--){
cnt=a[i]-'0'+b[i]-'0'+jw;
jw=cnt/10;
cnt%=10;
ans=char(cnt+'0')+ans;
}if(jw){
ans=char(jw+'0')+ans;
}return ans;
}
高精乘
string g_cheng(string a1,string b1){
string ans;
int c[100001],a[100001],b[100001];
memset(c,0,sizeof(c));
int lena=a1.length();
int lenb=b1.length();
for(int i=1;i<=lena;i++)a[i]=a1[lena-i]-'0';
for(int i=1;i<=lenb;i++)b[i]=b1[lenb-i]-'0';
for(int i=1;i<=lenb;i++){
for(int j=1;j<=lena;j++){
c[i+j-1]+=a[j]*b[i];
}
}for(int i=1;i<lena+lenb;i++){
if(c[i]>9){
c[i+1]+=c[i]/10;
c[i]%=10;
}
}int lens=lena+lenb;
while(c[lens]==0&&lens>1)lens--;
for(int i=lens;i>0;i--){
ans+=(c[i]+48);
}return ans;
}
主函数
int main(){
cin>>n;
for(int i=1;i<=n;i++){
string lin=g_jia("0","1");
for(int j=1;j<=i;j++){
int k=j;
string s;
while(k){
char ls=char(k%10+48);
s=ls+s;
k/=10;
}lin=g_cheng(lin,s);
}a=g_jia(a,lin);
}cout<<a;
return 0;
}
完整代码
#include<iostream>
#include<cstdio>
#include<cmath>
#include<iomanip>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
#include<stack>
#include<deque>
using namespace std;
int n;
string a="0";
string g_cheng(string a1,string b1){
string ans;
int c[100001],a[100001],b[100001];
memset(c,0,sizeof(c));
int lena=a1.length();
int lenb=b1.length();
for(int i=1;i<=lena;i++)a[i]=a1[lena-i]-'0';
for(int i=1;i<=lenb;i++)b[i]=b1[lenb-i]-'0';
for(int i=1;i<=lenb;i++){
for(int j=1;j<=lena;j++){
c[i+j-1]+=a[j]*b[i];
}
}for(int i=1;i<lena+lenb;i++){
if(c[i]>9){
c[i+1]+=c[i]/10;
c[i]%=10;
}
}int lens=lena+lenb;
while(c[lens]==0&&lens>1)lens--;
for(int i=lens;i>0;i--){
ans+=(c[i]+48);
}return ans;
}string g_jia(string a,string b){
int lena=a.length(),lenb=b.length();
if(lena<lenb){
for(int i=1;i<=lenb-lena;i++)a='0'+a;
}else{
for(int i=1;i<=lena-lenb;i++)b='0'+b;
}lena=a.length(),lenb=b.length();
int lens=lena;
int jw=0,cnt=0;
string ans;
for(int i=lens-1;i>=0;i--){
cnt=a[i]-'0'+b[i]-'0'+jw;
jw=cnt/10;
cnt%=10;
ans=char(cnt+'0')+ans;
}if(jw){
ans=char(jw+'0')+ans;
}return ans;
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
string lin=g_jia("0","1");
for(int j=1;j<=i;j++){
int k=j;
string s;
while(k){
char ls=char(k%10+48);
s=ls+s;
k/=10;
}lin=g_cheng(lin,s);
}a=g_jia(a,lin);
}cout<<a;
return 0;
}