编程之美2.2——不要被阶乘吓倒

N!中末尾0的个数


对N!进行质因数分解,N!可以分解成2^x * 3^y * 5^z*,只有2*5才会使N!的末尾产生1个0,
也就是说N!的质因数分解中有多少个2,5对末尾就有多少个0,而N!的质因数中5的个数要少于2的
个数,也就是说2,5对的个数取决于质因中5的个数,所以问题转化为求N!中质因数5的个数

5的个数Z=[N/5] + [N/5^2] + [N/5^3} + ...
[N/5] 表示不大于N的数中5的倍数贡献一个5,[N/5^2]表示不大于N的数中5^2的倍数再贡献一个5
32!= 1 * 2 * 3 * ...*31*32,其中5,10,15,20,30各贡献1个5,25贡献2个5,共7个5

int numOf0(int N)
{
 int result = 0;
 while(N)
 {
  N /= 5;
  result += N;
 }
 return result;
}


 

 

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


 
从右向左从1 数起
 
一个数的二进制表示中如果最后是m个0,则这个数有m个质因数2,如36的二进制表示为
 
100100,它最后有2个0,36=2*2*9,可以看到有2个2,则最低位的1,只比质因数2的个
 
数多一个,它在第2+1=3位
 
题目转化为求N!中含有质因数的个数,等于[N/2]+[N/4]+[N/8]+[N/16]+...
 
[N/2]表示不大于N的数中所有2的倍数贡献一个2*/
 

 int lowestOne(int N)
  {
   int result = 0;
   while(N)
   {
    N >>= 1;        //(N /= 2)
    result += N;
   }
   return  result;
  }


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值