题意
给你一个不小于
的整数
, 然后求
双阶乘的末尾
的个数。
思路:
我们知道要求阶乘尾部
的位数:
如果乘积要产生
的话,那么他们分解的因子中肯定会有
,又因为因子中
的个数肯定大于
的个数,所以我们直接考虑 5的位数就是最后0的位数。可写出如下程序:
int main(){
int n;
cin>>n;
int sum = 0;
while(n){
n /= 5;
sum += n;
}
cout<<sum;
}
那么这儿是双阶乘,那可怎么办呢?
可以发现,如果
为奇数的时候,一定没有0产生,所以我们只讨论
为偶数的时候。
我这儿有两种方法,本质是一样的,且同我徐徐道来。
对于
为偶数时,举个例子比如
,
根据上面求阶乘末尾0的个数的思想,我们只关心5的个数。
所以对于上面每一项我们除2得:
于是我们转化为求
的问题。
代码如下:
int main(){
ll n;
cin>>n;
if(n & 1) cout<<0;
else {
n /= 2;
ll sum = 0;
while(n){
n /= 5;
sum += n;
}
cout<<sum;
}
}
求阶乘中0的个数,其实是看阶乘中有多少5。类似的思想:
2能被5整除的次数是(2,4,,N中能被5整除的个数)+ (2,4,,N中能被
整除的个数)+ (2,4,,,N中能被
整除的个数)。分别是2,4,…, N中可以被5整除的个数是floor(N/10), 2,4, ., N中可以被
整除的个数是floor(N/50), 2,4, ., N中可以被
整除的个数是floor(N/250),…因此,从N/10开始,分母在N以下之间,分母增加5倍求商,这样反复进行,取其总和即可。
这种方法可能不如上面那么直观。
int main(){
ll n;
cin>>n;
if(n & 1) cout<<0;
else {
ll sum = 0;
ll x = n;
for(ll t = 10;(x/t)!=0;t *= 5){
sum += x/t;
}
cout<<sum;
}
}