表达式末尾的0

本文介绍了一种计算阶乘结果末尾连续零数量的方法。通过分析5因子的出现次数来确定零的数量,并提供了两种Python实现方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

表达式的结果中末尾连续的0出现的个数

牛客网:表达式末尾0的个数

题目描述

输入一个自然数n,求表达式 f(n) = 1!×2!×3!×…×n! 的结果末尾有几个连续的0?

输入描述:
自然数n

输出描述:
f(n)末尾连续的0的个数

思路:

这是一道找规律的题目。表达式的结果中末尾出现的0,只与两个数有关,那就是2和5。但事实上,我们通常不考虑2,所以只与一个元素有关,那就是5。为什么不考虑2呢,因为只要阶乘元素中出现了5的倍数,那么必定可以找到相应的偶数因子与这个5配对。因此可以不客气的说,一个5就对应一个末尾的0。

这里我们先考虑对于单个元素 n 的阶乘结果末尾0的个数:

比如,11的阶乘,阶乘的元素中有5,10这两个关键性的数。至于元素5,可以随意和任意偶数配对,使得结果末尾有一个0,至于10,我们仅把他当做“5”看待,那么这个“5”也定能找到相应的偶数(偶数不必是阶乘中的元素,元素中的因子也可以)结合。那么末尾中又有一个0。因此11的阶乘结果,末尾有两个0。

但是如果我们简单地只考虑 n 中包含多少个5,那么是得不到正确答案的。因为有特殊的元素,这个元素仅看作一个“5”是不对的。比如:25,125,625…。25可以看做两个“5”,125可以看做3个“5”,以此类推。那么新的问题来了,怎么计算“5”的总个数?首先我们找出 n 对 5 的取整a1,再找 n 对 25 的取整 a2,再找 n 对 125 的取整 a3…然后将所有的a(i)累加即可。注意是所有a(i)的累加,而不是 a 1 + 2 ∗ a 2 + 3 ∗ a 3....... a1+2*a2+3*a3....... a1+2a2+3a3....... 因为a1中计算5的取整时,也将25考虑在内了,因此计算25的取整时,尽管一个25的倍数可以看做两个“5”,由于之前已经计数过一次,所以只需要对当前计数一次就行。对于125以及625往后的取整,同理。

单个数的末尾0的计数已经搞清楚了,那么此题目的表达式是前 n 个元素阶乘的累乘。那就好办,遍历每个元素,对每个元素计数其中“5”的个数。累加之后就是答案。可是新的问题来了,计数时,125,625哪个是上限?这与 n 有关,如果 n 本身还没有 25 大,那么只需要与 5 取整就可以。如果 n 是 101,那么 n 与 5 和 25 取整就可以,不需要对 125 取整。所以 n 决定了取整的上限,那么怎么得到这个上限呢?对数函数log就可以!
k = i n t ( m a t h . l o g ( n , 5 ) ) k = int(math.log(n,5)) k=int(math.log(n,5))
k 就是最大幂次。好了,代码如下:(python3)
python2 只需要改动 input() 为 raw_input() 即可。

import math
n = int(input())
if n <=0:
    print(0)
else:
    res = 0
    k = int(math.log(n,5))
    for i in range(1,n+1):
        for j in range(1,k+1):
            res += i//(5**j)
    print(res)

这样的循环遍历,有点呆,因为对大部分数而言,最大上限的取整就是0。所以我们要换个思路,仍然要遍历每个元素,但我们计数“5”的个数时,稍稍变通。

class CountZero:
    def count(self, x):
        res, pre = 0, 0
        for i in range(5, x+1):
            while i%5 == 0:
                i //= 5
                pre += 1
            res += pre
        return res
k = int(input())
print(CountZero().count(k))

这里的pre变相的保存了相邻的前面元素的 “5” 的计数,这样不但省去了上面规律的讨论,而且这种接力计数很省时!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值