您的位置:首页 > 其它

关于阶乘的问题

2012-10-04 18:13 232 查看
来自《编程之美》的关于阶乘的题目:

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

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

这两道题的解法类似,先分析第二道题。

要求得N!的二进制表示中最低位1的位置,可将N!循环右移,直到无法被2整除为止,右移的次数即为最低位1之前0的个数,因此最低位1的位置就等于(右移次数 + 1)。

即若N = 0011(3),则 N! = 0110(6),那么N! / 2 = 0011奇数,无法继续被2整除,因此N!可右移一次,最低位1的位置等于 1 + 1 = 2(第二位)

所以该问题就可以转化为求 N! 的质因数 2 的个数

关于质因数,给出一个例子:

比如 18 = 2 * 3 * 3, 那么18的因数即为2和3, 质因数2的个数为1, 质因数3的个数为2。其中2, 3均为质数。

那么要如何求得N!的质因数2的个数?

在书中给出了这个一个公式:N!中含有质因数2的个数 = [N/2] + [N/4] + [N/8] + ...( [N/k] 表示1,2,3,4,...,N中能被k整除的数的个数 )

对于这个公式,自己现在还无法给出严格的数学证明,不过似乎也可以通过实例来理解。

例子:

当N = 8时, N! = 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1 = (2*2*2) * 7 * (2*3) * 5 * (2*2) * 3 * (2) * 1

1 ~ 8中:

能被2整除的数有 2, 4, 6, 8 ( 8 / 2 = 4 )

能被2^2(4)整除的数有 4, 8 ( 8 / 4 = 2 )

能被2^3(8)整除的数有 8 ( 8 / 8 = 1 )

一个数能被2整除,说明该数至少含有一个质因数2。

一个数能被2^2整除,说明该数至少含有两个质因数2。

……

可以把这个公式当做是一个统计过程——比如数字8,出现了3次,说明其包含了三个质因数2;4出现了两次,即包含两个质因数2;2, 6出现了一次,即分别包含一个质因数2

最后将每次统计的结果相加,即为总的质因数2的个数:4 + 2 + 1 = 7

那么相应的C程序为:

int lowestOne( int N )

{

int Ret = 0;

while( N )

{

N >>= 1; //即 N = N / 2

Ret += N;

}

return N;

}

那么第一题的解法也类似,即计算出N!中因数10的个数,转化为求N!中质因数5的个数。(10 = 2 * 5, 根据出现次数更少的5即可确定10出现的次数)

N!包含质因数5的个数 = [N/5] + [N/5^2] + [N/5^3]....

int NumOfZero( int N )

{

int ret = 0;

while( N )

{

ret += N / 5;

N /= 5;

}

return ret;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: