蓝桥杯刷题014——求阶乘(二分法)

news/2024/11/16 9:17:28/

求阶乘 

蓝桥杯2022省赛题目

问题描述

满足 N ! 的末尾恰好有 K 个 0 的最小的 N 是多少?

如果这样的 N 不存在输出 −1 。

输入格式

一个整数 K 。

输出格式

一个整数代表答案。

样例输入

2

样例输出

10

评测用例规模与约定

对于 30% 的数据, 1≤K≤10^6.

对于 100% 的数据, 1≤K≤10^18.

思路: 

题目大意:求满足N!的末尾恰好有K个0的最小的N,如果这样的N不存在,返回-1

解法一:暴力法

        遍历1~10^18(题目中100%的数据规模)内所有数,对每个数求阶乘,再计算末尾0的个数,最后判断是否为K个0,很明显是超时了(看下面代码分析)。但可以得到部分的分数,没有时间的话可以这样简单处理。

        代码分析:这个是计算末尾0的个数的代码,很明显在这个环节就没办法达到100%数据的要求,因为1≤K≤10^18,而这个代码复杂度是O(n),要计算10^18次,但蓝桥杯计算量一般不超过10^8,所以用暴力法计算是超时的。 

res = 0     # 统计末尾0的个数
while m % 10 == 0:res+=1m//10    # 去掉最后一位

解法二: 

解题关键给出一个N,如何快速计算它的阶乘中末尾0的个数?

  • 思考1:什么样的数,相乘后能够产生0?

10=2*5

20=2*2*5
7200=72*2*5*2*5
我们可以发现每个数字末尾的每个0都可以看成是2和5相乘得到
所以我们可以对题目中样例进行分析:10!=1 * 2 * 3 * 4 * 5* 6 * 7 * 8 * 9 * 10,我们发现10!内有一对现成的2和5,但样例输出是2,说明还有一对2和5,没错,只要把10进行分解成2*5就可以再得到一对,这样两对2和5说明10的阶乘末尾有2个零。

结论:给定一个数的阶乘,计算它的因子中2*5出现的次数,即可确定末尾0的个数 

  • 思考:2:找2*5的数目,因子2是否需要寻找?

不需要。通过10!=1 * 2 * 3 * 4 * 5* 6 * 7 * 8 * 9 * 10可以发现,因子5只有在5和10中才有。但因子2在2,4,6,8,10中都存在,出现2多5少的现象,所以只需要找到稀有的因子5即可,因为因子2是肯定有剩余的。

问题转换:

求N的阶乘尾部0的个数   ----->   求N的阶乘中因子5的个数
        对阶乘中的因子5进行分析,1 2 3 4 5…10 …15…20…25…30…35… 50…55… 75…100…105…125…,可以发现当到24时,前面每隔5都会都会有一对2和5,共有4对。但在25时会出两个5(两对2和5),总共就有6对,如果你输入5的话,没有末尾为5个0的阶乘,则返回-1。在124之前每隔25会出两对,但125会出三对。把前面出现的5加起来总共有31个,但这样很麻烦,有没有更容易操作的方法呢?看看下面的操作:

         为什么是这样算呢?是因为我们先把含有一个及以上5的25个数全部取出一个5加到总数num,那么本来一个5的数就变成0个(可以忽略),本来两个5的数变成一个5的数,本来3个5的变成二个5的。再这样对原本含有二个及以上5的5个数(现在是含有一个及以上5的数)操作一次,只剩下一个含5的数,最后再对含5的1个数取出一个5加到总数num,这样就把全部的因子5转移到了总数num。

结论:求N的阶乘中因子5的个数,将N每次除以5求和即可。

定义求一个整数阶乘末尾0的个数的函数:

def cal_zero(N):res = 0   # 统计0的个数while N:N //= 5res += Nreturn res

复杂度:每一次变成原来的五分之一,所以复杂度为O(log_5N),是logN级别的,计算10^18的数只需要算26次即可,非常高效!

注意:题目中 1≤K≤10^18的K是指整数阶乘末尾0的个数的范围,不是整数的范围,说明整数范围可能更大,我们以10^19的整数试一下,看看阶乘末尾0的个数能不能大于10^18。

def cal_zero(N):res = 0  # 统计0的个数while N:N //= 5res += Nreturn resN = 1e19
print(cal_zero(N))  # 2.5e+18

        很显然,10^19的整数阶乘末尾有2.5e+18个0,大于题目100%数据大小,是满足要求的。所以N可以取10^19来计算。

        上面只是求出了整数阶乘末尾0的个数,还需要找出满足末尾K个0的最小整数,下面用二分法来求解。

二分法登场啦!

使用条件:更小的N对应的是小的尾0个数,更大的N对应的是大的0个数,所以末尾0的个数是一个递增的有序数列,可以用二分法来求解。
定义一个check()函数:将所有从1到N的阶乘分成尾部0个数<k的左半部分和>=k的右半部分,二分结束后检查R位置(因为R是满足≥check()的最小值)的尾部0个数是否为k即可,若不是即返回-1。

def check(k):L,R=1,int(1e19)    while L+1!=R:mid = (L+R)//2if cal_zero(mid)>=k:    R = midelse:L=midif cal_zero(R)==k:  # cal_zero(r):满足阶乘末尾0≥k的最小整数return Relse:               # 没有阶乘末尾k个0的整数return -1   

 二分法的复杂度也是O(logN),所以算法复杂度为O((logn)^2)

代码演示: 

k=int(input())
def cal_zero(N):res = 0   # 统计末尾0的个数while N:N //= 5res += Nreturn res
def check(k):L,R=1,int(1e19)    while L+1!=R:mid = (L+R)//2if cal_zero(mid)>=k:    R = midelse:L=midif cal_zero(R)==k:  # cal_zero(r):满足阶乘末尾0≥k的最小整数return Relse:               # 没有阶乘末尾k个0的整数return -1   
print(check(k))


http://www.ppmy.cn/news/19688.html

相关文章

水面漂浮物垃圾识别检测系统 YOlOv7

水面漂浮物垃圾识别检测系统通过PythonYOLOv7网络模型&#xff0c;实现对水面漂浮物以及生活各种垃圾等全天候24小时不间断智能化检测。Python是一种由Guido van Rossum开发的通用编程语言&#xff0c;它很快就变得非常流行&#xff0c;主要是因为它的简单性和代码可读性。它使…

【每日一道智力题】之坤坤猜生日(面试高频)

&#x1f680;write in front&#x1f680; &#x1f4dc;所属专栏&#xff1a;每日一题 &#x1f6f0;️博客主页&#xff1a;睿睿的博客主页 &#x1f6f0;️代码仓库&#xff1a;&#x1f389;VS2022_C语言仓库 &#x1f3a1;您的点赞、关注、收藏、评论&#xff0c;是对我最…

ArrayList类

ArrayList类 目录ArrayList类一、构造方法摘要1.1 ArrayList()1.2 ArrayList(Collection c)1.3 ArrayList(int initialCapacity)二、 ArrayList的扩容机制&#xff1a;2.1 源码如下&#xff1a;2.2. 以上扩容机制的弊端&#xff1a;三、代码案例ArrayList类一、构造方法摘要 1…

【C语言课堂】 函数递归

欢迎来到 Claffic 的博客 &#x1f49e;&#x1f49e;&#x1f49e; 前言&#xff1a; 时隔多日&#xff0c;来还欠大家的 C 语言学习啦&#xff0c;上期讲了函数&#xff0c;其实函数中应该包括函数递归的&#xff0c;这里单独拿出来讲解的原因是函数递归属于重难知识&#xf…

8. 好客租房-WebSocket与即时通讯系统[项目必需]

本章节主要是学习WebSocket, 目标快速入门, 能够回答以下问题:WebSocket和HTTP的区别.WebSocket使用的是全双工通讯协议, 与其他类似协议有啥区别?WebSocket中的常用注解有哪些&#xff1f;通过本章节的学习, 应该可以回答上来这几个问题.8.1 WebSocket概念快速理解WebSocket …

【Linux】目录权限和默认权限

上期介绍了Linux的文件权限&#xff0c;这期我们仔细来说说Linux环境下目录权限和默认权限一、目录权限1.1 进入目录所需的权限我们在进入目录时需要什么样的权限呢&#xff1f;是r、w还是x呢&#xff1f;下面我们一起来验证一下&#xff1a;&#x1f4cb;如下我门拥有全部目录…

2-SAT

前置核心知识&#xff1a;强连通分量&#xff08;tarjan算法&#xff09; 1&#xff0c;定义 给定n个集合&#xff08;每个集合都是有2个元素&#xff09;&#xff0c;再给出m个关系式&#xff08;形式大致是aVb1),求是否能够从每个集合选一个元素&#xff0c;并且元素满足上…

Citadel——Dusk网络的Zero-Knowledge KYC解决方案

1. 引言 近期&#xff0c;Dusk网络宣布其已支持名为Citadel的Zero-Knowledge KYC解决方案&#xff0c;使得用户和机构可控制其权限以及个人信息分享。该架构可用于all claim-based KYC requests&#xff0c;并让用户完全控制他们共享的信息以及与谁共享信息&#xff0c;同时完…