• 关于阶乘的问题


    来自《编程之美》的关于阶乘的题目:

        1.给定一个整数N,那么N的阶乘N!末尾有多少个0呢?例如:N = 10, N! = 3628800,N!的末尾有两个0

        2.求N!的二进制表示中最低位1的位置。

    这两道题的解法类似,先分析第二道题。

        要求得N!的二进制表示中最低位1的位置,可将N!循环右移,直到无法被2整除为止,右移的次数即为最低位1之前0的个数,因此最低位1的位置就等于(右移次数 + 1)。

        即若N = 0011(3),则 N! = 0110(6),那么N! / 2 = 0011奇数,无法继续被2整除,因此N!可右移一次,最低位1的位置等于 1 + 1 = 2(第二位) 

        所以该问题就可以转化为求 N! 的质因数 2 的个数

        关于质因数,给出一个例子:

            比如 18 = 2 * 3 * 3, 那么18的因数即为2和3, 质因数2的个数为1, 质因数3的个数为2。其中2, 3均为质数。

        那么要如何求得N!的质因数2的个数?

        在书中给出了这个一个公式:N!中含有质因数2的个数 = [N/2] + [N/4] + [N/8] + ...( [N/k] 表示1,2,3,4,...,N中能被k整除的数的个数 )

        对于这个公式,自己现在还无法给出严格的数学证明,不过似乎也可以通过实例来理解。

        例子:

            当N = 8时, N! = 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1 = (2*2*2) * 7 * (2*3) * 5 * (2*2) * 3 * (2) * 1

            1 ~ 8中:

                能被2整除的数有 2, 4, 6, 8    ( 8 / 2 = 4 )

                能被2^2(4)整除的数有 4, 8    ( 8 / 4 = 2 )

                能被2^3(8)整除的数有 8    ( 8 / 8 = 1 )

            一个数能被2整除,说明该数至少含有一个质因数2。

            一个数能被2^2整除,说明该数至少含有两个质因数2。

            ……

            可以把这个公式当做是一个统计过程——比如数字8,出现了3次,说明其包含了三个质因数2;4出现了两次,即包含两个质因数2;2, 6出现了一次,即分别包含一个质因数2

            最后将每次统计的结果相加,即为总的质因数2的个数:4 + 2 + 1 = 7

    那么相应的C程序为:

    int lowestOne( int N )

    {

        int Ret = 0;

        while( N )

        {

            N >>= 1;  //即 N = N / 2

            Ret += N;

        }

        return N;

    }

    那么第一题的解法也类似,即计算出N!中因数10的个数,转化为求N!中质因数5的个数。(10 = 2 * 5, 根据出现次数更少的5即可确定10出现的次数)

    N!包含质因数5的个数 = [N/5] + [N/5^2] + [N/5^3]....

    int NumOfZero( int N )

    {

        int ret = 0;

        while( N )

        {

            ret += N / 5;

            N /= 5;

        }

        return ret;

    }

  • 相关阅读:
    【YbtOJ#911】欧拉函数
    【CF590E】Birthday
    打印控件的区别
    RPA教程
    UiPath培训教程
    RPA视频教程
    搭建samba服务
    kvm虚拟机在线扩容
    zabbix监控交换机
    UiPath Level3讲解
  • 原文地址:https://www.cnblogs.com/liangchao/p/2711603.html
Copyright © 2020-2023  润新知