题目:魔法石的诱惑

分析一

想要做出这个题,首先得知道:给定一个正整数n,怎么快速计算出n的阶乘尾部0的个数

这种题嘛,主要是找规律,找出规律来后就很简单了。ok,先想想,阶乘最后有0,如果一个偶数和5相乘,不就有0吗?还有其他情况吗,当然10,15,20这种的乘偶数也有0,但10,15,20不也能分解成5乘某个数吗?

如:
OOO代表偶数


5=5∗4∗3∗2∗15=5*4*3*2*15=5∗4∗3∗2∗1
2∗O2*O2∗O最后肯定有一个0


10=10∗9∗8∗7∗6∗5∗4∗3∗2∗110 = 10*9*8*7*6*5*4*3*2*110=10∗9∗8∗7∗6∗5∗4∗3∗2∗1
10∗O,5∗O10*O,5*O10∗O,5∗O有两个0


18=18∗17∗16∗15...∗10...∗5...∗118 = 18*17*16*15...*10...*5...*118=18∗17∗16∗15...∗10...∗5...∗1
15∗O,10∗O,5∗O15*O,10*O,5*O15∗O,10∗O,5∗O有两个0


25=25∗...∗20∗...∗15∗...∗10∗...525=25*...*20*...*15*...*10*...525=25∗...∗20∗...∗15∗...∗10∗...5


ok问题来了25∗4=10025*4=10025∗4=100这里有俩0,怎么判断呢?
很简单啊,25=5∗525=5*525=5∗5这里能分解成两个5,再随便俩偶数不就有俩0了吗?
再往前看10的阶乘,10=2∗510=2*510=2∗5,这里其实也相当于一个5乘了一个偶数。

哦,这样的话规律就找到了,就看这个数按阶乘展开后,能被分解成多少个5就有多少个0,25有5∗5=25,4∗5=20,3∗5=15,2∗5=10,55*5=25,4*5=20,3*5=15,2*5=10,55∗5=25,4∗5=20,3∗5=15,2∗5=10,5一共6个5,经过计算,确实6个5

s = 1
for i in range(1,26):s *=i
print(s)15511210043330985984000000

原理搞明白了就看看有多少个5就行了。ok搞代码

先从简单的来,如15的阶乘,可以直接循环,看有几个除5,余数为0即可。
然后看25这种的,余数也为0,那怎么判断呢?
25%5=0,但25/5=5,所以如果先判断他的余数是否为0,如果为0,count就加1,然后再判断25/5除5的余数是否还为0。
那125有三个5,咋判断呢?很简单啊,用个while循环,一直让他除5,等于0就count+1,除5再判断,再判断。最终代码如下:

count = 0
n = 28
if n < 5:print(n,"没有0")
else:for i in range(5,n+1,5): #  这里从5开始。每隔5个数才会被除一次,其他书肯定被5除不开,所以也不用判断增加时间复杂度while i%5 == 0:  #先判断能否被5整除count += 1 # 如果能被5整除,则count+1i = i/5 # 再算一下cout/5之后还能否被5整除,循环相加print("{}有{}个0".format(n,count))

分析二:提高

当输入99999999时,计算要好大一会,时间复杂度为O(N/5)~=O(N),总感觉里面还有规律,可以让时间复杂度降的更低。ok再找找。

其实分析上面的数列可知,每5个数中会出现一个可以产生结果中0的数字。把这些数字抽取出来是:

...、5、...、10、...、15、...、20、...、25、......、5、...、10、...、15、...、20、...、25、......、5、...、10、...、15、...、20、...、25、...

这些数字是5的倍数。统计一下他们的数量:n1=N/5。比如28,则之前应该是5,10,15,20,25共28//5=5个数字满足要求。

整理一下:5*(1,2,3,4,5),即28能直接提取5个5

(1,2,3,4,5)里面还能再提取一个5这就是6个5


再比如78,则之前应该是5,10,15,20,25…75

整理一下:5*(1,2,3,4,5…25)即75能直接提取75//5=25个数字。

(1,2,3,4,5…25)里面还能再提取(5、10、15、20、25)(5、10、15、20、25)(5、10、15、20、25)
整理一下:5*(1,2,3,4,5),这里即25//5=5个5,

(1,2,3,4,5)里面又能提取1个5,即一共25+5+1=31个5,即阶乘后有31个0。


规律差不多能看出来了,即先找出里面有几个能直接被5整除的,然后再看整除商(即n//5得到的数)能有几个被5整除,再反复循环找下去,知道整除商不能被5整除,即小于5停止。
ok搞代码:

def trailingZeros(n):count = 0while n >=5: # 整除商小于5后就可以不计算了,肯定没有5的倍数了count += n // 5  # 先加直接能直接提取的5的个数n //= 5         # 再从整除商里提取能被5整除的个数print(n)return count
trailingZeros(9999999)

原题解法

书上给的分治算法有点难懂,时间复杂度也大,所以我直接使用上面分析得到的结果会比较直观。

上面分析的可以结果其实是先找有几个能被5直接整除的,再找几个能被525^252整除的,再53,...5k5^3,...5^k53,...5k,再加起来即可。
即Q=n/5+N/52+...+n/5kQ = n/5+N/5^2+...+n/5^kQ=n/5+N/52+...+n/5k

等比数列求和:Q=n4∗(1−15k)Q=\frac{n}{4}*(1-\frac{1}{5^k})Q=4n​∗(1−5k1​)
因为15k\frac{1}{5^k}5k1​是接近1的,但小于1,所以n是约等于4Q的,但一定比4Q稍大,所以:
n≈Q∗4n≈Q*4n≈Q∗4

这样求解就简单了:

def trailingZeros(n):count = 0while n >=5: # 整除商小于5后就可以不计算了,肯定没有5的倍数了count += n // 5  # 先加直接能直接提取的5的个数n //= 5         # 再从整除商里提取能被5整除的个数return counttrailingZeros(2679)q = 666 # 输入值
n = 4*q  # 大体值,但最终数肯定要比4*q大
n = n-n%5  # 5是分界线,减去被5除的余数即可得到最小自然数
while True: s = trailingZeros(n)  if q > s: # q>s说明数小了,稍微提高一点n +=5elif q<s:print(n,s,"unknow")breakelse:print(n,s)break

算法每日一题--分治算法(二)-李富贵要上岸985相关推荐

  1. 卷王李富贵算法每日一题--分治算法(三)--逃亡

    逃亡 如图1.2所示,设两人分别为甲.乙,则最优方案应该是甲先乘车到达C后下车步行,小车回头接已经走到E的乙,假设在 D相遇,乙乘车到达B时正好甲也步行到达,这样花费的时间最短. 分治算法 v1 是人 ...

  2. 算法每日一题--分治算法(一)-李富贵要上岸985

    文章目录 前言 注 分治算法(一) 例题一:二分查找(折半查找) 递归法 踩坑 非递归 前言 之前主要是学人工智能相关的知识,从Python基础到数据分析到人工智能等等,那些知识一般是用到了,学习的过 ...

  3. 卷王李富贵算法每日一题--分治算法(四)--循环比赛

    循环比赛 ## 问题: 有N个运动员进行单循环赛,即每个运动员要和所有其他运动员进行一次比赛.1.试用分治法为N个运动员安排比赛日程. 要求每个(或队)运动员每天只能进行一场比赛,且当运动员人数(队数 ...

  4. 2022AcWing寒假算法每日一题之2058. 笨拙的手指

    2022AcWing寒假算法每日一题之2058. 笨拙的手指 题目链接:AcWing2058. 笨拙的手指 思路: 1.数据范围为0-1e9,则输入的时候按照字符串输入 2.将二进制和三进制各位数上的 ...

  5. 【备战蓝桥】 算法·每日一题(详解+多解)-- day1

    [备战蓝桥] 算法·每日一题(详解+多解)-- day1 ✨博主介绍 什么是蓝桥杯 第一题: 第二题 第三题 第四题 第五题 第六题 第七题

  6. 【备战蓝桥杯】 算法·每日一题(详解+多解)-- day11

    [备战蓝桥杯] 算法·每日一题(详解+多解)-- day11 ✨博主介绍 前言 Dijkstra 算法 流程 网络延迟时间 解题思路 Bellman-Ford 算法 流程 K 站内最便宜的航班 解题思 ...

  7. 哈工大(威海)算法实验一:分治算法实验大作业

    哈工大(威海)算法实验一:分治算法实验大作业 题目 某一高等院校有汽车学院.材料学院.计算机学院.软件学院:每个学院的一年级第一学期都开英语.高数.线代课程.每个学院每学期的成绩已经分别登录在同一个E ...

  8. C#LeetCode刷题-分治算法

    分治算法篇 # 题名 刷题 通过率 难度 4 两个排序数组的中位数 C#LeetCode刷题之#4-两个排序数组的中位数(Median of Two Sorted Arrays)-该题未达最优解 30 ...

  9. NOIP训练营集训笔记—信息学基础算法(倍增与分治算法

      本文摘自清北OI学堂内部笔记,作者潘恺璠,来自柳铁一中曾参加过清北训练营提高组精英班,主要记录的是信息学基础算法.笔记非常详细,特分享给大家! NOIP2019年夏令营正在报名中,6大校区10种班 ...

最新文章

  1. Python:numpy实现生成随机数,忽略warnings
  2. python在线课程-开始网上在线深度学习python课程
  3. 关于CString的=操作符
  4. oracle清理asm归档日志,【Oracle】 rman 删除归档日志的命令
  5. python二进制图片压缩传输_python 中 base64 压缩图片,用post传送
  6. mac下ssh 报错:localhost: ssh: connect to host localhost port 22: Connection refused
  7. 国人常用密码TOP100 FROM THISITE
  8. Windows安全中心打不开,无法启动
  9. .NET Framework v2.0 Obsolete APIs - 与大家分享
  10. pm2.5计算和单位换算
  11. SEO基本概念之死链接
  12. 联想thinkpad E430C硬盘位换为固态,硬盘放于光驱位(win7+win10+ubuntu三系统安装教程)
  13. [TensorFlow深度学习深入]实战一·使用embedding_lookup模块对Word2Vec训练保存与简单使用
  14. ChinaSoft 论坛巡礼 | 优秀博士生论坛
  15. 微信小程序开发基础(03视图与逻辑)
  16. 当贝OS版本更新:当贝智慧盒子Z1 Pro新增边看边聊,一起在线吐槽神剧
  17. 环形穿梭车(RGV)高效搬运设计方法
  18. 机器人履带底盘的悬挂和传动
  19. 计算机毕业设计SSM大学生学习交友平台【附源码数据库】
  20. 2022 leetcode 春季赛 LCP 53. 守护太空城

热门文章

  1. 【debug】使用lambda在循环中传参时,参数总为同一个值
  2. 怎么扩展磁盘_电脑怎么增加C盘空间 小白教你不花钱增加C盘空间
  3. 正态分布函数_从微积分角度证明“正态分布密度函数”
  4. 广州专科计算机学校录取分数线,广州大专多少分能录取?高考分数170分能上广州大专?...
  5. android 图片操作,Android图片操作(Bitmap)
  6. freemodbus收藏学习网址
  7. 532 -数组中的K-diff对
  8. 《重构-改善既有代码的设计》学习笔记(二)
  9. python3 抓取图片
  10. myeclipse 8.5 注册码