• Algorithm --> 求阶乘末尾0的个数


    求阶乘末尾0的个数

    1)给定一个整数N,那么N的阶乘N!末尾有多少个0?比如:N=10N=3628800N!的末尾有20

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

    第一题

    考虑哪些数相乘能得到10N!= K * 10M其中K不能被10整除,则N!末尾有M0。

    N!进行质因数分解: N!=2X*3Y*5Z…,因为10=2*5,所以M25的个数即XZ有关。每一对25都可以得到10,故M=min(X,Z)。因为能被2整除的数出现的频率要比能被5整除的数出现的频率高,所以M=Z

    解法1问题转化为求N!因式分解中5的指数。

    int countZero(int N)
    {
         int ret = 0;
         int j;
         for(int i=1; i<=N; i++)
         {
               j = i;
               while(0==j%5)
               {
                   ret++;
                   j /= 5;
               }
         }
         return ret;
    }

     改进不要从1开始循环的,只有5的倍数才能够被5整除

    int numOfZero(int n)  
    {  
        int num = 0, i, temp;  
        for(i=5; i<=n; i+=5)  
        {  
            temp = i;  
            while(0 == temp%5)  
            {  
                temp /= 5;  
                num++;  
            }  
        }  
        return num;  
    }  

    解法2Z =[N/5] + [N/52] + [N/53] + …

    [N/5] 表示不大于N的的数中5的倍数贡献一个5, [N/52] 表示不大于N的数中52的倍数在贡献一个5……

    int countZero(int N)
    {
         int ret = 0;
         while(N)
         {
               ret += N/5;
               N /= 5;
         }
         return ret;
    }

     或者

    int numOfZero(int n)  
    {  
        int num = 0, i;  
        for(i=5; i<=n; i*=5)  
        {  
            num += n/i;  
        }  
        return num;  
    }  

    第二题

    把一个二进制除以2的过程如下:

    判断最后一个二进制是否为0:若为0将二进制数右移1位,即为商;若为1,则说明这个数是奇数,不能被2整除。

    所以判断N!的二进制表示中最低位为1的位置的问题可以转换为求N!中含有质因数2的个数的问题。即位置为N!含有质因数2的个数加1.

    解法1N!中含有质因数2的个数等于:[N/2]+[N/4]+[N/8]+…

    int lowestOne(int N)
    {
         int ret = 1;
         while(N)
         {
               N >>= 1;
               ret += N;
         }
         return ret;
    }

    解法2N!中含有质因数2的个数等于N减去N的二进制表示中1的数目。

    以下为规律的推导:N!中含有2的质因数的个数等于[N/2]+[N/4]+[N/8]+…

    对于11011即:

    1101+110+11+1 = (1000+100+1) + (100+10) + (10+1) + 1

    = 1000+100+10+1 + 100+10+1 + 1

    = 1111+111+1

    = 10000-1 + 1000-1 + 10-1 + 1-1

    11011-(N的二进制表示中含有1的个数)

  • 相关阅读:
    C++11特性
    DBC文件小结
    关于宏定义
    CentOS 6.5下Zabbix的安装配置
    CentOS下搭建LAMP环境详解
    VS2010中汉字拷贝到Word出现乱码问题解决
    DLL注入
    数组赋值
    CDC的StretchBlt函数载入位图时图片失真问题
    2019年下半年Web前端开发初级理论考试
  • 原文地址:https://www.cnblogs.com/jeakeven/p/4907089.html
Copyright © 2020-2023  润新知