给定一个整数N,那么N的阶乘N!末尾有多少个0呢?求N!的二进制表示中最低位1的位置。

时间:2021-04-12 02:10:38

题目1:给定一个整数N,那么N的阶乘N!末尾有多少个0呢?例如:N=10,N!=3 628 800,N!的末尾有两个0。

初看这样的题目可能会想到直接求出N!的阶乘,然后再计算出0的个数。

显然用这种方法如果N很大的情况下,非常容易溢出。所以我们可以换个角度来分析这个问题。N=1×2×3×4×5×6×··· ×N我们可以对N!进行分解质因数 即N!=2x ×3y ×5z ··········可以看到2和5相乘必然会产生一个10,而这个10会在阶乘的末尾添加一个0。那么问题就转化为2x ×5z 可以产生多少个0,即min(x,z),显然X肯定大于Z(能被2整除的数肯定比5多),最终问题转化为求Z的值-即找出1...N能分解出多少个5, 程序如下:

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

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

问题2要求的是N!的二进制表示中最低位1的位置。给定一个整数N,求N!二进制表示的最低位1在第几位?

例如:给定N= 3,N!= 6,那么N!的二进制表示(1 010)的最低位1在第二位。  

为了得到更好的解法,首先要对题目进行一下转化。  

首先来看一下一个二进制数除以2的计算过程和结果是怎样的。  

把一个二进制数除以2,实际过程如下:  

判断最后一个二进制位是否为0,若为0,则将此二进制数右移一位,即为商值(为什么);反之,若为1,则说明这个二进制数是奇数,无法被2整除(这又是为什么)。 所以,这个问题实际上等同于求N!含有质因数2的个数。即答案等于N!含有质因数2的个数加1。

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