问题一:给定一个整数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]+....