时间限制: 1000 ms 内存限制: 65536 KB
提交数: 1493 通过数: 689
【题目描述】
用高精度计算出S=1!+2!+3!+…+n!(n≤50),其中“!”表示阶乘,例如:5!=5×4×3×2×1。输入正整数n,输出计算结果S。
【输入】
一个正整数n。
【输出】
计算结果S。
【输入样例】
5
【输出样例】
153
【来源】
No
【代码】
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;
int a[40000]={1},ans[40000]={1};
int b,t,la=1,lans=1;
//进行阶乘运算
void jiecheng(int j)
{
b=0;
for(int k=0;k<la;k++) //进行乘法运算
{
t=a[k]*j+b;
b=t/10; //除法将个位提出去
a[k]=t%10; //取模将个位提出来,赋值为数组a[]
}
while(b>0) //进行进位,并将m的值进行了加1
{
a[la++]+=b%10;
b/=10;
}
}
//进行加法运算
void jia()
{
int x=0;
lans=lans>la?lans:la; //判断lans与m谁大,lans大就lans=lans,m大就lans=m
for(int i=0;i<lans;i++) //计算和
{
ans[i]=ans[i]+a[i]+x; //要注意计算的和是哪两个的值相加
x=ans[i]/10;
ans[i]%=10;
}
if(x>0) //如果最后x>0,那么就让数组长度+1之后进位
{
ans[lans++]=x;
}
}
int main()
{
//a[0]=1;
int n;
cin>>n;
for(int i=2;i<=n;i++)
{
jiecheng(i); //算阶乘
jia(); //算和
}
while(ans[lans]==0)
{
lans--; //要将和的前导0删掉
}
for(int i=lans;i>=0;i--) //输出时要逆序输出
{
cout<<ans[i];
}
return 0;
}
【解题思路】
难点:如何将大整数加法与阶乘结合在一起
1.建议大家去看一下我前面写的1168:大整数加法与1172:求10000以内n的阶乘 这两个解题思路。本题是两者的结合,阶乘函数一模一样,加法函数做了稍许改变,在做加法的时候是和数组ans与阶乘数组a进行的加法运算。
//进行加法运算
void jia()
{
int x=0;
lans=lans>la?lans:la; //判断lans与m谁大,lans大就lans=lans,m大就lans=m
for(int i=0;i<lans;i++) //计算和
{
ans[i]=ans[i]+a[i]+x; //要注意计算的和是哪两个的值相加
x=ans[i]/10;
ans[i]%=10;
}
if(x>0) //如果最后x>0,那么就让数组长度+1之后进位
{
ans[lans++]=x;
}
}
2.这里还有另一种算阶乘与加法的思路,给大家参考,其实也差不多,只是有一点变化,大家有兴趣就自己看一下吧。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;
int len=1,anslen=1;
int t[40000]={0,1},ans[40000]={0};
void jiecheng (int v)
{
for(int i=1;i<=len;i++)
{
t[i]=t[i]*v;
}
int j=1;
while(t[j]>9||j<=len)//进位
{
t[j+1]=t[j]/10+t[j+1];
t[j]=t[j]%10;
j++;
}
len=j;
}
void jia()
{
anslen=anslen>len?anslen:len;
for(int i=1;i<=anslen;i++)
{
ans[i]=ans[i]+t[i];
if(ans[i]>9)
{
ans[i+1]+=ans[i]/10;
ans[i]%=10;
}
}
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
jiecheng(i);
jia();
}
while(ans[anslen]==0) anslen--;
for(int k=anslen;k>=1;k--)
{
cout<<ans[k];
}
return 0;
}