【阶乘】阶乘相关的题

1、如何求N的阶乘所得的数字末尾含有多少个0

分析问题:

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,

方法1、

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

方法2、
求n!中5的个数,
举个例子 16!中的包含5的只有,15,10,5这三个数,这个三个数分别包含了 3个5,2个5,1个5,一共有6个5,
所以可以分别求出他们中5的个数再累加。

int countFactorialZero(int n) 
{
    int count =0;
    while(n)
    {
     count += n/5;
     n = n/5;
    }
    return count;
}
2、求N!的二进制表示中最低位1的位置

分析问题:

乍一看,似乎,问题二与问题一没什么关系。然而,我们换一个角度思考,二进制中最低位1后面肯定是0,那么这里求最低位1的位置,即为求最低位1后面0的个数,而这,就和问题一是一样一样的,只不过一个是十进制表,一个是二进制表示。这里,所有小于N的数中,2的倍数都贡献一个0,4的倍数再贡献一个0,以此类推。

最关键:由于二进制表示其实是以2为基的表示,每出现一个2,末尾才会有一个0。所以只要找到N!中因子2的个数。

  所以,这个问题实际上等同于求N!含有质因数2的个数。即答案等于N!含有质因数2的个数加1。

  由于N! 中含有质因数2的个数,等于 N/2 + N/4 + N/8 + N/16 + … ,根据上述分析,得到具体算法,如下所示:

方法1
和问题1中的方法2思路一样。

int lcoalLastOne(int n)
{
    int count = 0;//求出0的个数
    while(n)
    {
        n = n >> 1;
        count += n;
    }
    return count+1;//返回加1、
}

方法2、

N!含有质因数2的个数,还等于N减去N的二进制表示中1的数目,然后再加1
而对于求N的二进制中1的个数,通过n=n&(n-1),累加计数器 计算出来,上一篇博客求N二进制表示中1的个数

int lcoalLastOne(int n)
{
    //先计算出n中1的个数
    int temp = n;
    int count = 0;
    while(temp)
    {
     ++count;
     temp = temp&(temp-1);
    }
    //返回n-1的个数 再加1
    return n-count+1;
}
3、给定整数n,判断它是否为2的方幂

n的二进制表示中,如果只有一个1的话,那么该整数就是2的方幂。
那就是就该整数 最右边的1去掉,看是否==0,
即 n&(n-1) ==0, 如果等于0,就是2的方幂。

  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值