hdu 1042 n!(大整数阶乘模板)

来源:互联网 发布:青年网络公开课罗思义 编辑:程序博客网 时间:2024/05/22 00:49

大整数乘法求阶乘

初学时,用迭代法或递归法就可以计算出n阶乘,但n稍大时,int或者longlong都满足不了,要用到大整数思想

如hdu1042

用数组储存结果的方法

#include <iostream>using namespace std;int s[100005];int main(){    int n,k,ans,a;    while(cin>>n)    {        s[0]=1;//每一次的结果被分成个十百千等位,分别放在s中,如s[0]放个位数        a=1;//每一次阶乘结果的位数        ans=1;//中间值        for(int i=2;i<=n;i++)        {            k=0;            for(int j=0;j<a;j++)            {                ans=s[j]*i+k;//i同每一位的乘积,k为进位                s[j]=ans%10;//更新各个位上的数                k=ans/10;            }             while(k)//k进位,扩大位数a             {                s[a++]=k%10;                k/=10;            }        }        for(int i=a-1;i>=0;i--)            cout<<s[i];        cout<<endl;    }    return 0;}

另外是大神们写的什么万进制的啊


#include<cstdio>#include<cstring>#define N 8000   //要求最大是10000!,可以计算一下大概是5+9000*4+900*3+90*2+10*1=38865位,//正常来说,要开N 40000//若用数字,一个元素存5位,N只需要8000就可以了int s[N];int main(){    int n;    int i,j,t,y;    while(scanf("%d",&n)==1)    {        if(n==0)        {            printf("1\n");            continue;        }        memset(s,0,sizeof(s));        s[1]=1;        t=1;        for(i=2; i<=n; i++)              //s数组的所有位数表示当前计算出的结果        {            y=0;            for(j=1; j<=t; j++)            {                s[j]=s[j]*i+y;                y=s[j]/100000;                s[j]%=100000;            }            while(y)                     //有余进位            {                s[++t]=y%100000;                y/=100000;            }        }        printf("%d",s[t]);              //去前置零        for(i=t-1; i>=1; i--)            printf("%05d",s[i]);        //格式化输出,每一个s代表了结果中的5位数        printf("\n");    }    return 0;}



再就是求n!的位数

解法1:1+lg(1)+lg(2)+..+lg(n) 
解法2:strling公式:n!的位数=log10(sqrt(2*pi*n))+n*log10(n/e) 

如poj1423   用斯特林

整数n的位数的计算方法为:log10(n)+1
故n!的位数为log10(n!)+1
由于这是高精度没法用普通方式计算阶乘,否则会TLE
可以用斯特林(Stirling)公式求解
斯特林(Stirling)公式  :
所以求n!的位数就是求log10(sqrt(2*pi*n))+n*log10(n/e)
更快是  log10(2*pi*n)/2.0+n*(log10(n/e))

#include<iostream>#include<cmath>using namespace std;const double e=2.718281828459;const double pi=3.14159265359;double strling(int n){ return log10(2*pi*n)/2.0+n*(log10(n/e));     //0ms //return log10(sqrt(2*pi*n))+n*log10(n/e);   //16ms}int main(){ int t,n,ans; scanf("%d",&t); while(t--) {  scanf("%d",&n);  ans=(int)strling(n)+1;  printf("%d/n",ans); } return 0;}

码: http://www.cnblogs.com/qlwy/archive/2012/07/18/2598028.html

    http://blog.csdn.net/shiwei408/article/details/8739433



1 0