zoukankan      html  css  js  c++  java
  • 求 n! (大数问题)----------HDOJ1042

    以下只YY算法,c++实现,java大神绕道。。。。。

    (1)位数的估计

        显然对于大数(比如1000的阶乘)的阶乘我们找不到一个数据类型存放这个数,是在太大啦。。。。

        那么现在来估计一下这个数的位数:

     

        估计数n的位数的方法:log10(n)+1;

        那么log10(n!)+1=log10(1)+log10(2)+...log10(n)+1,这在计算机中是很容易解决的;

        ps:斯特林公式:n! approx sqrt{2pi n}\, left(frac{n}{e}
ight)^{n}.也可以用它两边取对数求得;

        斯特林公式推导

        

    #include<cstdio>
    #include<cmath>
    int main()
    {
        int n,i;
        double d;
        while(scanf("%d",&n)!=EOF)
        {
            d=0;
            for(i=1; i<=n; i++)
                d+=log10(i);
            printf("%d
    ",(int) d+1);
        }
        return 0;
    }

    (2)求解n!的大小

         看一个例子1567*12=18804:

       我们把前一个数分开为15、67,67*12=804、15*12=180,有下列狮子:

                 15      67

       *                 12

    -----------------------------

                 8       04

        1       80

    -----------------------------

        1       88       04


    那么,计算n的阶乘的时候,n-1的阶乘肯定是很大的,(n-1)!*n就恰好是一个大数乘以一个小的数字;

    比如我们计算0到1000的阶乘,那么计算1000!的阶乘有2568位,这个数就决定数组的要开的大小,开打啦会超时,开小啦不够,我们用一个数组存放阶乘,每一个数组单元存放4位,就可以计算出来啦,详情见代码中的注释吧!

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<string>
    #define maxs 10000
    //数组的设置的大小,不能开太大,这样的话扫描的时间太长会超时,也不能太小。。。。
    using namespace std;
    int a[maxs];
    int main()
    {
        int n,i,j,y;
        while(scanf("%d",&n)!=EOF)
            {
               memset(a,0,sizeof(a));//把数组全部设置为0
               for(i=1,a[maxs-1]=1;i<=n;i++)//数组的高位存放数的低位,把最低位置成1,从1乘到n
                {
                    y=0;//余数
                    for(j=maxs-1;j>=0;j--)
                        {
                          a[j]=a[j]*i+y;
                          y=a[j]/10000;//得到乘法之后的结果
                          a[j]=a[j]%10000;//得到进位
                        }
                }
                for(i=0;i<maxs;i++)//从左到右扫描,第一个不是0的跳出
                   if(a[i])break;
                printf("%d",a[i++]);//输出第一个不是0的
                for(j=i;j<maxs;j++)
                    printf("%04d",a[j]);//注意中间的数字,比如12,由于在数的中间要输出0012
                printf("
    ");
            }
      return 0;
    }
    
    


  • 相关阅读:
    node.js 安装后怎么打开 node.js 命令框
    thinkPHP5 where多条件查询
    网站title中的图标
    第一次写博客
    Solution to copy paste not working in Remote Desktop
    The operation could not be completed. (Microsoft.Dynamics.BusinessConnectorNet)
    The package failed to load due to error 0xC0011008
    VS2013常用快捷键
    微软Dynamics AX的三层架构
    怎样在TFS(Team Foundation Server)中链接团队项目
  • 原文地址:https://www.cnblogs.com/riskyer/p/3266610.html
Copyright © 2011-2022 走看看