蓝桥杯-求阶乘-python

 问题描述

满足N!的末尾恰好有K个0的最小的N是多少?
如果这样的N不存在输出一1。

蓝桥杯-求阶乘-python_第1张图片

思路解析

末尾的0是由10产生的,而10是由质数2和5产生的

在求阶乘的过程中,只要是偶数就会有2,而5相对2更少,所以对于10的数量我们可以用计算5的数量来代替

所以我们的目标就是求1-N中有多少个5

1-5,1-10,1-15,1-20,1-25,分别有1,2,3,4,5+1个5

不难看出,5的个数是最后一个数除以5的商(直至不够除5,因为有些数包括多个5,例如25,包含了两个5)

def five_count(num):
  count = 0
  while  !(num%==5) :
    #商即为5的个数,可以看作是1*5,2*5,3*5... 1,2,3就是包括前面数字中的5的个数的总和
    count += num//5
    num = num//5
  return count

因为要求的N要求最小,即N一定是5的倍数

但是范围太大,即使我们只找5的倍数,还是会超时,

既然是查找,我们便可以利用二分法

l = 1
r = 10**19

while(l

由于二分循环条件是l

所以在最后还要考虑l=r的情况

#当r==l时
if k == five_count(l):
  print(l)

但是二分法查找的不仅仅是5的倍数,因此我们要考虑非5的倍数

对于非5倍数,我们考虑最接近该数的小于他的5的倍数,换一个说法,即考虑该数除5的商,不考虑余数

我们只需要把循环条件改成num//5即可

def five_count(num):
  count = 0
  #不是5的倍数也可以
  while (num//5):
    #商即为5的个数,可以看作是1*5,2*5,3*5... 1,2,3就是包括前面数字中的5的个数的总和
    count += num//5
    num = num//5
  return count

完整代码

import os
import sys

# 请在此输入您的代码
#计算从1~num中有多少个5,不是5的倍数也可以
def five_count(num):
  count = 0
  #不是5的倍数也可以
  while (num//5):
    #商即为5的个数,可以看作是1*5,2*5,3*5... 1,2,3就是包括前面数字中的5的个数的总和
    count += num//5
    num = num//5
  return count

k = int(input())
l = 1
r = 10**19


while(l> 1)
  mid = (l+r)//2
  ct = five_count(mid)

#一直循环到最接近的结果或符合条件的最终结果
  if ct < k:
    l = mid + 1
  else:
    r = mid
#l、r、mid三者最后均相等
#当r==l时
if k == five_count(l):
  print(l)
else:
  print(-1)

你可能感兴趣的:(程序设计,python,开发语言,蓝桥杯)