2.2不要被阶乘吓到!

问题:1,求N!末尾有多少个0?

   2,N!的二进制表示中最低位1的位置?

问题1的解法一:

如果N!= K×10M,且K不能被10整除,那么N!末尾有M个0。再考虑对N!进行质因数分解,N!=(2^x)×(3^y)×(5^z)…,由于10 = 2×5,所以M只跟X和Z相关,每一对2和5相乘可以得到一个10,于是M = min(X, Z)。不难看出X大于等于Z,因为能被2整除的数出现的频率比能被5整除的数高得多,所以把公式简化为M = Z。问题相当于求N!中有质因数5的个数。

解法二:Z=[N/5]+[N/5^2]+[N/5^3]……

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

问题二解法一:
这个问题实际上等同于求N!含有质因数2的个数。即答案等于N!含有质因数2的个数加1。
N!中含有质因数2的个数,等于 N/2 + N/4 + N/8 + N/16 + …

也就是N!最多能整除2的多少次幂。(同问题一解法二类似)

int LowestOne(int N){
    int num=0;
    while(N){
             N>>=1;
             num+=N;
             }
    return num;
    }

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

扩展问题:

给定整数n,判断它是否是2的方幂(n>0&&((n&(n-1))==0))

原文地址:https://www.cnblogs.com/relaxgirl/p/2988258.html