只看最终答案请跳至最后
对于一个正整数,求这个正整数的阶乘的结果末尾有多少个0,例如正整数31的阶乘结果为8222838654177922817725562880000000,末尾有7个0。
看到这个题目,最直观的想法是除了暴力估计没得其他方法了,暴力求解方法如下:
n = int(input().strip())
res = 1
for i in range(1, n+1):
res *= i
print(res)
flag = 10
final_res = 0
while res % flag == 0:
final_res += 1
flag *= 10
print(final_res)
在考试的时候这种方法虽然空间复杂度非常大,但是也能AC通过83%,看到这个结果,说明肯定有其他简单的解法来处理这个问题,然后我想到,只要结果中出现10,那这个数跟任何数相乘末尾肯定是0,比如
对于整数10,参与阶乘的整数如下:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
其中
2 * 5 == 10
10 == 10
也就是说,每十个数中肯定会出现一次个位数为2、个位数为5和个位数为0的整数
11-20 : [22, 25, 30]
21-30 : [32, 35, 40]
31-40 : [42, 45, 50]
:
:
:
这样一来我每增加5个数,末尾的0就应该是增加1个
n = 20
res = 1
for i in range(1, n+1):
res *= i
print(res)
flag = 10
final_res = 0
while res % flag == 0:
final_res += 1
flag *= 10
print(final_res) #输出4
res = 0
i = 5
while i <= n:
res += 1
i += 5
print(res) #输出4
但是随着整数增大会发现出错,原来是25、50、125、150等数对末尾0的贡献不是1,而是2、2、3、2,也就是这个数能被多少个5整除
n = 31 #输入的正整数
i = 5
final_res = 0
while i <= n:
k = i
while k % 5 == 0:
final_res += 1
k //= 5
i += 5
print(final_res)
最后的结果是全部AC通过且特变快,只需24ms