输入一个自然数n,求表达式 f(n) = 1!*2!*3!*.....*n! 的结果末尾有几个连续的0?
输入描述:
自然数n
输出描述:
f(n)末尾连续的0的个数
输入例子1:
11
输出例子1:
9
示例代码1:【此方法遇到大数会运行超时】
from functools import reduce
def sums(n):
if n == 1:
return 1
else:
return reduce(lambda x, y: x * y, range(1, n + 1)) * sums(n - 1)
num = int(input('请输入一个n:'))
result = sums(num)
print(result)
res = 0
flag = True
while flag and result:
if result % 10 == 0:
result //= 10
res += 1
continue
flag = False
print(res)
运行结果:
示例代码2:
def func(x):
res, tmp = 0, 0
for i in range(5, x+1):
while i % 5 == 0:
i //= 5
tmp += 1
res += tmp
return res
num = int(input('请输入一个数n:'))
result = func(num)
print(result)
运行结果:
思路解析:
这是一道找规律的题目。表达式的结果中末尾出现的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)累加即可。因为a1中计算5的取整时,也将25考虑在内了,因此计算25的取整时,尽管一个25的倍数可以看做两个“5”,由于之前已经计数过一次,所以只需要对当前计数一次就行。对于125以及625往后的取整,同理。
单个数的末尾0的计数已经搞清楚了,那么此题目的表达式是前 n 个元素阶乘的累乘。那就好办,遍历每个元素,对每个元素计数其中“5”的个数。累加之后就是答案。