N的阶乘末尾有多少个0
思考:0来自何方?
10*10*10*。。。乘以10就会产生0。
那么N!可以写成下面这种形式:
且K不能被10整除,那么N!的末尾就有M个0。
那么M是多少呢=>将N!进行质因数分解
需要M个2和M个5来组成M个10,N!一共有X个2,Z个5,所以M=min(X,Z);
偶数都能被2整除,都能贡献出质数2来,能被5整除的就相对就少很多。所以M=min(X,Z)=Z
=======现在问题就转化成,求N!含有质因数5的个数即Z=======
方法1:遍历1~N,sum(每个数贡献出来的5个个数)
以25!为例,25!=1*2*3*……*25,如下图所示,5,10,15,20,都贡献了5:5=5*1贡献了1个,10=5*2也贡献了一个质因数5也贡献了一个质因数2,25=5*5,贡献了2个质因数5
ret = 0;
for(int i=1;i<=N;++i){
j = i;
while(j % 5 == 0){//若j有质因数5
++ret;//质因数个数加1
j /= 5;//整除5,再循环看看还有没有质因数5了
}
//若j==25,那么第一次j%5判断有质因数5,则ret+1;j=25/5;
//再循环判断是否还有质因数5,还有,则ret+1,j=5/5;
//再循环判断是否还有质因数5,j为1,所以已经没有质因数了,while循环结束
}
以25!为例解释公式:
如图所示,1~25个数中一共贡献了6个5.
(其中5的倍数贡献5个5,25的倍数再贡献1个5)
:1~25这25个数中有多少个5的倍数?他们至少每个贡献一个5。5、10、15、20、25加起来贡献5个5.
:1~25这25个数中有多少个25的倍数,就只有一个25是25的倍数。除去了作为5的倍数贡献出来的1个质因数5,他至少再贡献一个5。所以25再贡献一个质因数5.
代码:
ret=0
while(N){
N/=5;
ret+=N;
}