【牛客题霸题解】阶乘末尾0的数量

阶乘末尾0的数量

http://www.nowcoder.com/practice/aa03dff18376454c9d2e359163bf44b8

观察一下10以内的数字互相乘,会发现,只有





相乘会产生0,而且 ...
所以我们只需要看一下 以内 能拆出多少对
然后我们可以发现,有5因子的数比有2因子的数要少,所以我们就看能拆出来多少5就可以了,因为肯定能有足够数量的因子2来匹配。

所以阶乘末尾0的数量就是 中能拆出来的5的数量。但是,从 1 遍历到 n 每个数看一下它能除多少次 5 是不行的。因为 n 的数据范围是1e18。遍历1e18个数复杂度太大了。
那我们来考虑一下,5的倍数可以至少产生1个5,25的倍数可以产生至少2个5,125的倍数可以产生至少3个5...
这样的话 中有n/5个5的倍数,n/25个25的倍数,n/125个125的倍数...
所以答案就是 n/5+n/25+n/25...

c++

class Solution {
public:
    long long thenumberof0(long long n) {
        long long ans = 0;
        long long d = 5;
        while(n>=d)
        {
            ans+=n/d;
            d = d*5;
        }
        return ans;

    }
};

java

import java.util.*;
public class Solution {
    public long thenumberof0 (long n) {
        long ans = 0;
        long d = 5;
        while(n>=d)
        {
            ans+=n/d;
            d = d*5;
        }
        return ans;
    }
}

python

class Solution:
    def thenumberof0(self , n ):
        ans = 0
        d = 5
        while n>=d:
            ans+=n//d
            d = d*5
        return ans
牛客题霸题解 文章被收录于专栏

QAQ

全部评论
1~n 中有 n/5 个 5 的倍数, 有 n/25 个 25 的倍数, ... , 之所以最后结果是 n/5 + n/25 + n/125 + ... , 而非 n/5 + 2*n/25 + 3*n/125 + ... , 是因为 n/25 的 2 个 5 有 1 个在 n/5 的时候已经计算过了一遍. 如果倒过来计算的话, 假设除以 k 次幂时按照其贡献了 k 个 5, 在计算 k-1 次幂时, 应当用 k-1 乘以是 5^(k-1) 的倍数且不是 5^k 的倍数的数字的个数, 在计算 k-2 次幂时, 应当用 k-2 乘以是 5^(k-2) 的倍数且不是 5^(k-1) 以及 5^k 的倍数的数字的个数(只需要减去 5^(k-1) 的倍数的数字的个数即可, 因为其包含了 5^k 的倍数的数字). k*n/5^k + (k-1)*(n/5^(k-1) - n/5^k) + (k-2)*(n/5^(k-2) - n/5^(k-1)) + ... + 1*(n/5 - n/5^2). 以 n 为 125 为例, 3*125/5^3 + 2*(125/5^2 - 125/5^3) + 1*(125/5^1 - 125/5^2) = 125/5^3 + 125/5^2 + 125/5 = 31
3 回复 分享
发布于 2021-09-03 15:28
也可以换个角度思考.对于n!,单独拿出能产生因子5的数,则可以表示成5*(n/d)!.实际每次遍历就是计算规模为n/d^k的子问题,k是递归次数
点赞 回复 分享
发布于 2022-11-09 10:57 广东

相关推荐

2025-12-13 20:26
浙江大学 Java
淬月星辉:把浙大的校名加大加粗,把校徽再贴出来,就OK了
点赞 评论 收藏
分享
评论
28
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务