P1009 [NOIP1998 普及组] 阶乘之和 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
由于直接算,所有类型的变量(double int long long)都会溢出,
所以用字符串储存数字,模拟乘法
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
//12349
//9
//
string add(string a, string b) //模拟加法
{
string res;
int carry=0;//记录进位
int i,j;
for(i=a.size()-1,j=b.size()-1;i>=0||j>=0;i--,j--)
{
int temp=(i>=0?a[i]:'0')+(j>=0?b[j]:'0')-'0'-'0'+carry;
//如果某个串遍历完了,就当前面全是0计算
if(temp>=10){temp-=10;carry=1;}//有进位 处理
else carry=0;
res+=temp+'0';
}
if(carry)res+='1';//处理最后的进位
reverse(res.begin(), res.end());
return res;
}
string Mutiple(string last,int n)//模拟乘法 last*n (n最大为50)
{
int carry=0;
string res1;
int low=n%10;
if(low!=0)//处理第1位
{
for(int i=last.size()-1;i>=0;i--)
{
int num=(last[i]-'0')*low+carry;
if(num>=10)
{
carry=num/10;
num%=10;
}
else carry=0;
res1+=num+'0';
}
if(carry)res1+=carry+'0';
reverse(res1.begin(),res1.end());
}
carry=0;
string res2;
int second=n/10;
if(second)//处理第二位 (其实处理1/2位的逻辑都是一样,都可按照个位处理,最后在结果的后面加上若干0)
{//这里也可抽象到函数 ,本题50最多两位数就这样简单处理了
for(int i=last.size()-1;i>=0;i--)
{
int num=(last[i]-'0')*second+carry;
if(num>=10)
{
carry=num/10;
num%=10;
}
else carry=0;
res2+=num+'0';
}
if(carry)res2+=carry+'0';
reverse(res2.begin(),res2.end());
res2+='0';
}
string res=add(res1,res2);
return res;
}
int main()
{
int n;
cin>>n;
string num="1";
string sum="0";
for(int i=1;i<=n;i++)
{
num=Mutiple(num,i);
sum=add(sum,num);
}
cout<<sum;
return 0;
}
大数加法(字符串存储)通用版
int transfer(char c)
{
if(c>='A'&&c<='f')
return c-'A'+10;
else return c-'0';
}
string add(string &a, string &b,int n) //模拟加法 n进制
{
string res;
int carry=0;//记录进位
int i,j;
for(i=a.size()-1,j=b.size()-1;i>=0||j>=0;i--,j--)
{
int temp=(i>=0?transfer(a[i]):0)+(j>=0?transfer(b[j]):0)+carry;
//如果某个串遍历完了,就当前面全是0计算
if(temp>=n)
{temp-=n;carry=1;}//有进位 处理
else carry=0;
if(temp>=10){char ch='A'+temp-10;res+=ch;}
else res+=temp+'0';
}
if(carry)res+='1';//处理最后的进位
reverse(res.begin(), res.end());
return res;
}