第一次写博客(就从最基础的高精开始吧)题号:1009
其实这道题就是考察OIer对高精度算法的掌握程度,没有什么很难的地方。
说一下基本思路:循环N次,每一次计算出i的阶乘,然后用数组存储结果,并将此结果与上一次储存的结果进行相加,最后输出。
include<iostream>
include<cstdio>
include<cstring>
using namespace std;
int a[10000],c[100000],g[100000],h[10000],o[100000];//在竖式计算x*y==z中,a表示x,c表示z;在竖式计算x+y==z中,g表示x,h表示y,o表示z
string s1="0";
void jiafa(string x)//用得到的i的阶乘与之前的结果的阶乘相加
{
int i,l1=s1.length(),l2=x.length(),x1=0;
memset(g,0,sizeof(g));//数组清零
memset(h,0,sizeof(h));//数组清零
memset(o,0,sizeof(o));//数组清零
for(i=0;i<l1;i++) g[l1-i]=int(s1[i]-48);
for(i=0;i<l2;i++) h[l2-i]=int(x[i]-48);
i=1;
while(i<=l1||i<=l2)//高精加法
{
o[i]=g[i]+h[i]+x1;
x1=o[i]/10;
o[i]%=10;
i++;
}
o[i]=x1;
s1="";
if(o[i]==0) i--;//去除前导0
for(;i>=1;i--)//s1记录结果
s1+=char(o[i]+48);
}
void chengfa(int n)//计算i的阶乘
{
int i,k,j,x=0,m,l=1,l1;
a[1]=1;//初始化赋值
string s="";//初始化赋值,s表示阶乘计算x!中x!的值
for(i=1;i<=n;i++)
{
memset(c,0,sizeof(c));//数组清零
m=i;
j=0;
while(m>0)//算出每一个数位上的数字
{
j++;//用来表示竖式计算x*y==z中y的位数
x=0;
for(k=1;k<=l;k++)//高精乘法,l表示竖式计算x*y==z中x的位数
{
c[j+k-1]+=m%10*a[k]+x;
x=c[j+k-1]/10;
c[j+k-1]%=10;
}
c[j+l]=x;
m/=10;
}
l+=j;//高精乘法结论
while(c[l]==0&&l>1) l--;//去除前导0
l1=l;
for(;l1>=1;l1--)
a[l1]=c[l1];//竖式计算x*y==z中,将z的值赋给x并进行下一次乘法
}
for(;l>=1;l--)//计算完阶乘后,将结果赋给s,并进行加法运算
s+=char(a[l]+48);
jiafa(s);//进行加法
}
int main()//这里是非常重要的一点,我推荐大家以后写算法用函数,不要全写在主函数内,主函数尽量简洁
{
int n,i;
scanf("%d",&n);
for(i=1;i<=n;i++)//每次计算i的阶乘
{
chengfa(i);
}
cout<<s1;//输出结果
while(1) cout<<"1";//防“沉迷”系统,以后不再提醒
return 0;
}