题目描述
已知正整数N(N<=100),设S=1!+2!+3!+…N!。其中"!"表示阶乘,即N!=123*……(N-1)N,如:3!=123=6。请编程实现:输入正整数N,输出计算结果S的值。
输入
输入一个整数n( 1<= n<=100)
输出
输出s的值
样例输入
4
样例输出
33
这里n最大为100,普通的数据类型无法满足运算,要使用高精度求积和高精度求和才能计算出准确答案
#include<iostream>
#include<cstdlib>
#include<string>
#include<algorithm>
#include<cmath>
using namespace std;
// 超长整数*个位数
string small_mul(string s1,int c1){
if(c1==0) return "0";
else if(c1==1) return s1;
reverse(s1.begin(),s1.end());
string sum="";
// cc表示进位
int temp=0,cc=0;
for(int i=0;i<s1.length();i++){
temp=(s1[i]-'0')*c1+cc;
cc=temp/10;
sum+=temp%10+'0';
}
if(cc!=0)sum+=cc+'0';
reverse(sum.begin(),sum.end());
return sum;
}
string get_sum(string s1,string s2){
reverse(s1.begin(),s1.end());
reverse(s2.begin(),s2.end());
string sum="";
int temp=0,cc=0;
string maxstr=s1.length()>s2.length()? s1:s2;
int minlen=s1.length()>s2.length()? s2.length():s1.length();
for(int i=0;i<minlen;i++){
temp=(s1[i]-'0')+(s2[i]-'0')+cc;
cc=temp/10;
sum+=temp%10+'0';
}
// 考虑两个加数位数不同
for(int i=minlen;i<maxstr.length();i++){
temp=(maxstr[i]-'0')+cc;
cc=temp/10;
sum+=temp%10+'0';
}
// 考虑到最高位仍有进位
if(cc!=0)sum+=cc+'0';
reverse(sum.begin(),sum.end());
return sum;
}
string big_mul(string s1,string s2){
reverse(s2.begin(),s2.end());
int add=0;
string sum="",tempstr="";
for(int i=0;i<s2.length();i++){
tempstr=small_mul(s1,s2[i]-'0');
// 每加一次0,就相当于乘以10,乘法需要依次乘1,10,100,1000...
for(int k=0;k<add;k++){
tempstr+='0';
}
sum=get_sum(sum,tempstr);
add++;
}
return sum;
}
int main(){
int n;
cin>>n;
string sum="",temp="1";
for(int i=1;i<=n;i++){
// temp储存N!
temp=big_mul(temp,to_string(i));
sum=get_sum(sum,temp);
}
cout<<sum<<endl;
}
该程序用于计算1到N的阶乘之和,使用了自定义的高精度乘法和加法函数,以处理超过普通数据类型限制的大整数运算。通过逐次计算每个数的阶乘并累加到总和中,最终输出结果。
1049

被折叠的 条评论
为什么被折叠?



