代码改变世界

Programe_Of_Beauty:2.2 不要被阶乘吓到

2011-06-06 13:54  x_feng  阅读(257)  评论(0)    收藏  举报

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

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

问题1书上的解析一:

例如N=10,我们发现这个数中5*2=10,如N=100呢?5*20=100,5*4=20,…如果一个数中有几个5那么这个数就贡献几个0.只要计算N!中出现多少次5就能确定末尾有多少个0.

num = 0;
for (int i = 1; i <=N; i++)//计算阶乘中每一个数中5出现的次数
{
    int j = i;
    while(j %5 == 0)//说明能被5整除,有一个5
    {
        num++;
        j = j/5;
    }
}

问题1书上的解析二:

还有没有简便的方法呢?例如N=110,我们看看110!,它所有出现5的情况(即能被5整除的数)5*22,5*21,5*20,5*19,…,5*5,5*4,5*3,5*2,5*1,我们发现提取5后面是一个递减的序列5*(22,21,20,19,18,…,5,4,3,2,1),那么110除5=22,表示能被一个5整除的数的个数。那么序列(22,21,20,19,18,…,5,4,3,2,1)还有5的存在,像20,15,10,5这几个数,那么我们再开看看这个序列中出现5的情况,5*4,5*3,5*2,5*1,提取5剩下的序列(4,3,2,1),那么22除以5=4,表示这个序列中还有4个5.由此我们可以推算出:先求N!中能被一个5整除的个数,再求能被两个5整除的个数,再求能被三个5整除的个数……

num = 0;
while(N)
{
    num += N/5;
    N = N/5;
}

问题2书上的解析一:N!的二进制表示中最低位1的位置,其实就是转化为求N!中2出现的次数。

num = 0;
while(N)
{
    num += N/2;
    N = N/5;
}
//也可以通过位移计算
num = 0;
while(N)
{
    N>>=1;
    num += N;
}

其它方法就不再赘述了,想了解更多就查书吧。