第一次写博客(就从最基础的高精开始吧)题号: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;
}

posted @ 2017-12-09 12:13  最爱丁珰  阅读(28)  评论(0编辑  收藏  举报