蓝桥杯-求阶乘-python

 问题描述

满足N!的末尾恰好有K个0的最小的N是多少?
如果这样的N不存在输出一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<r):
  mid = (l+r)//2
  ct = five_count(mid)
#一直循环到最接近的结果或符合条件的最终结果
  if ct < k:
    l = mid + 1
  else:
    r = mid

由于二分循环条件是l<r,(l<=r可能会造成死循环)

所以在最后还要考虑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<r):
  #mid = l + ((r - 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)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值