编程之美读书笔记之---”不要被阶乘吓到“

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

问题二:求N! 的二进制表示中,最低位1的位置。

问题一的解法一:

最简单的方法就是把N! 算出来,就可以知道末尾有多少个0了。

问题一的解法二:

我们这样想,末尾的0可以从哪里得到呢,10的倍数,例如像10,20,100....这样的,可以贡献0,还有就是2 * 5这样也可以得到一个0,不过我们可以发现,10其实也是从5得来的,

10 = 2 * 5,

20 = 4 * 5,

100 = 20 * 5

所以,我们可以得出,有多少个0,就看N!的因式分解中含有多少个5,。至此,成功的将原问题转化成一个更简单的问题。

利用这个原理,我们提出两种解决方法求因式分解中因子5的个数:

1、第一种方法很简单,就是直接拆分5出来

int tot = 0;    //因子5的个数

for(int i = 1;i <= N;i++)

{

    int temp = i;

    while(temp % 5 ==0 )

    {

        tot++;

        temp /= 5;

    }

}

2、第二种方法tot = [N / 5] + [N / 5^2] + [N / 5^3]+.....看N除以5得多少,其实就是N!中,能被5整除的因子有多少个,然后每个因子可以贡献一个5,例如26!,[26/5] = 5,就有5,10,15,20,25这五个能被5整除的。然后能被5^2整除的因子可以贡献两个5,例如像25这样的,所以又要再加一次除以5^2的因子的个数,以此类推.....

int tot = 0;

int c = 5;

while(c <= N)

{

    tot += (tot / N);

    c *= 5;

}

问题二:

我们知道一个整除除以2可以用右移1位来代替,当一个数可以被2整除的时候,二进制的最低位是0,当最低位是1的时候就是奇数,不能被2整除,所以,我们可以得出一个数可以被2整除多少次,就说明这个数的二进制最低位有多少个0。换一种说法就是这个数2的因子的个数。于是又有:

一个数N的阶乘N!的二进制最低位0的个数 = [N / 2] + [N / 2^2] + [N / 2 ^ 3]+....

原文地址:https://www.cnblogs.com/xiaxiaosheng/p/4813091.html