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

news2025/1/12 13:25:18

求阶乘 

蓝桥杯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+=1
    m//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个,但这样很麻烦,有没有更容易操作的方法呢?看看下面的操作:

求125的阶乘尾部0的个数
125!                                                                               
 简化版:  对每次除以5的商求和
125//5=25     说明含有一个及以上5的数有25个                           125//5=25
125//25=5     说明含有二个及以上5的数有5个                               25//5=5     
125// 125 =1 说明含有三个及以上5的数有1个                                 5//5=1 
将三个数加起来:总数num=25+5+1=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 //= 5
        res += N
    return 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 //= 5
        res += N
    return res

N = 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)//2
        if cal_zero(mid)>=k:    
            R = mid
        else:
            L=mid
    if cal_zero(R)==k:  # cal_zero(r):满足阶乘末尾0≥k的最小整数
      return R
    else:               # 没有阶乘末尾k个0的整数
      return -1   

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

代码演示: 

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

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/179196.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

新瑞鹏冲刺上市:持续亏损,旗下宠物医院屡被罚,彭永鹤为董事长

家门口的宠物医院所属集团也要上市了。 1月24日&#xff0c;新瑞鹏宠物医疗集团有限公司&#xff08;New Ruipeng Pet Group Inc.&#xff0c;下称“新瑞鹏”或“新瑞鹏集团”&#xff09;在美国证监会&#xff08;SEC&#xff09;公开提交招股书&#xff0c;准备在美国纳斯达…

LabVIEW什么时候需要实时系统

LabVIEW什么时候需要实时系统实时计算系统能够非常可靠地执行具有非常具体时序要求的程序&#xff0c;这对于许多科学和工程项目来说都很重要。构建实时系统所需的关键组件是实时操作系统&#xff08;RTOS&#xff09;。精确计时对于许多工程师和科学家来说&#xff0c;在安装了…

C 语言零基础入门教程(十)

C 作用域规则 任何一种编程中&#xff0c;作用域是程序中定义的变量所存在的区域&#xff0c;超过该区域变量就不能被访问。C 语言中有三个地方可以声明变量&#xff1a; 1、函数或块内部的局部变量 2、在所有函数外部的全局变量 3、在形式参数的函数参数定义中 让我们来看看什…

返回值的理解

前言 我们写的函数是怎么返回的&#xff0c;该如何返回一个临时变量&#xff0c;临时变量不是出栈就销毁了吗&#xff0c;为什么可以传递给调用方&#xff1f;返回对象的大小对使用的方式有影响吗&#xff1f;本文将带你探究这些问题&#xff0c;阅读本文需要对函数栈帧有一定…

Win10+GTX3060+Python+PyTorch+Tensorflow安装

本文是个备忘录&#xff0c;是折腾半个下午的成果&#xff0c;记下来免得忘记了。 0. 安装Win10&#xff0c;安装显卡驱动程序。 1. 弄清楚目前版本的PyTorch和Tensorflow支持哪个版本的Python。截至本文编写时&#xff0c;PyTorch需要Python的3.7~3.9&#xff0c;Tensorflow…

【NI Multisim 14.0虚拟仪器设计——放置虚拟仪器仪表(字发生器)】

目录 序言 &#x1f34d;放置虚拟仪器仪表 &#x1f349;字发生器 &#xff08;1&#xff09;“控件”选项组 &#xff08;2&#xff09;“显示”选项组 &#xff08;3&#xff09;“触发”选项组 &#xff08;4&#xff09;“频率”选项组 &#xff08;5&#xff09;字符…

CSS 艺术之暗系魔幻卡牌

CSS 艺术之暗系魔幻卡牌参考描述效果支线HTML图片主线去除元素的部分默认属性定义 CSS 变量body#card自定义属性定义动画#card::before#card::afterimg代码总汇参考 项目描述MDNWeb 文档搜索引擎Bing 描述 项目描述Edge109.0.1518.61 (正式版本) (64 位) 效果 注&#xff1a;…

DaVinci:HDR 调色

调色页面&#xff1a;HDR 调色Color&#xff1a;HDR GradeHDR 调色 HDR Grade调板不仅可用于 HDR 视频的调色&#xff0c; 也可用于 SDR 视频。其调色功能与标准色轮类似&#xff0c;但能调整的区域却要细致很多&#xff0c;同时&#xff0c;它还是可感知色彩空间的工具。高动态…

41.Isaac教程--使用DOPE进行3D物体姿态估计

使用DOPE进行3D物体姿态估计 ISAAC教程合集地址: https://blog.csdn.net/kunhe0512/category_12163211.html 深度对象姿态估计 (DOPE:Deep Object Pose Estimation) 从单个 RGB 图像执行已知对象的检测和 3D 姿态估计。 它使用深度学习方法来预测对象 3D 边界框的角点和质心的…

【数据结构】单调栈、单调队列

单调栈 单调栈 单调 栈 模拟单调递增栈的操作&#xff1a; 如果栈为 空 或者栈顶元素 大于 入栈元素&#xff0c;则入栈&#xff1b;否则&#xff0c;入栈则会破坏栈内元素的单调性&#xff0c;则需要将不满足条 件的栈顶元素全部弹出后&#xff0c;将入栈元素入栈。 单调…

研究分析如何设计高并发下的弹幕系统

一、需求背景为了更好的支持直播业务&#xff0c;产品设计为直播业务增加弹幕功能,但是最初的弹幕设计使用效果并不理想&#xff0c;经常出现卡顿、弹幕偏少等需要解决的问题。二、问题分析按照背景来分析&#xff0c;系统主要面临以下问题&#xff1a;带宽压力&#xff1b;弱网…

[基础]qml基础控件

TextText元素可以显示纯文本或者富文本(使用HTML标记修饰的文本)。它有font,text,color,elide,textFormat,wrapMode,horizontalAlignment,verticalAlignment等属性。主要看下clip&#xff0c;elide&#xff0c;textFormat&#xff0c;warpMode属性clipText 项目是可以设置宽度的…

Apache Spark 机器学习 特征抽取 4-2

Word2Vec 单词向量化是一个估算器&#xff0c;将文档转换成一个按照固定顺序排列的单词序列&#xff0c;然后&#xff0c;训练成一个Word2VecModel单词向量化的模型&#xff0c;该模型将每个单词映射成一个唯一性的、固定大小的向量集&#xff0c;对每个文档的所有单词进行平均…

【数据结构和算法】实现线性表中的静态、动态顺序表

本文是数据结构的开篇&#xff0c;上文学习了关于使用C语言实现静态、动态、文件操作的通讯录&#xff0c;其中使用到了结构体这一类型&#xff0c;实际上&#xff0c;是可以属于数据结构的内容&#xff0c;接下来我们来了解一下顺序表的相关内容。 目录 前言 一、线性表 一…

流批一体计算引擎-6-[Flink]的Python DataStream API程序

参考官方Python API文档 1 IDEA中运行Flink 从Flink 1.11版本开始, PyFlink 作业支持在 Windows 系统上运行&#xff0c;因此您也可以在 Windows 上开发和调试 PyFlink 作业了。 1.1 环境配置 pip3 install apache-flink1.15.3 CMD>set PATH查看环境变量 CMD>set JAV…

对JDBC驱动注册--DriverManager.registerDriver和Class.forName(driverClass)的理解

对JDBC驱动注册–DriverManager.registerDriver和Class.forName(driverClass)的理解 JDBC提供了独立于数据库的统一API&#xff0c;MySQL、Oracle等数据库公司都可以基于这个标准接口来进行开发。包括java.sql包下的Driver&#xff0c;Connection&#xff0c;Statement&#x…

注解方式管理Bean

1.注解方式创建对象IOC 导入依赖 aop Component(父注解) 放在类上,用于标记,告诉spring当前类需要由容器实例化bean并放入容器中 该注解有三个子注解 Controller 用于实例化controller层bean Service 用于实例化service层bean Repository 用于实例化持久层bean 当不确定是哪一…

【刷题大本营】二叉树进阶oj题(动图讲解,附代码及题目链接)

&#x1f525;&#x1f525; 欢迎来到小林的博客&#xff01;&#xff01;       &#x1f6f0;️博客主页&#xff1a;✈️小林爱敲代码       &#x1f6f0;️欢迎关注&#xff1a;&#x1f44d;点赞&#x1f64c;收藏✍️留言       这篇文章给大家带来一…

RK3399平台开发系列讲解(文件系统篇)文件回写过程介绍

🚀返回专栏总目录 文章目录 一、编程接口二、回写过程2.1、周期回写2.2、强制回写2.3、系统调用sync沉淀、分享、成长,让自己和他人都能有所收获!😄 📢进程写文件时,内核的文件系统模块把数据写到文件的页缓存,没有立即写回到存储设备。文件系统模块会定期把脏页(即…

[JavaEE]线程池

专栏简介: JavaEE从入门到进阶 题目来源: leetcode,牛客,剑指offer. 创作目标: 记录学习JavaEE学习历程 希望在提升自己的同时,帮助他人,,与大家一起共同进步,互相成长. 学历代表过去,能力代表现在,学习能力代表未来! 目录: 1. 线程池是什么? 2. 线程池的实现原理 3. 标准…