二分法(蓝桥杯Python组)

二分法

二分法(Binary Search)主要用于在有序数组中搜索恰好满足某一边界条件的元素。如果题目所求的答案具有是或者不是两种状态,则说明其可能是二分法的题目。同时还需要注意蓝桥杯通常不会直接出题考察二分法,而是将其内嵌到其他算法中联合考察,该算法往往应用于快速在某一定义域区间中枚举出正确答案。

一、算法模板

(一)调用库函数

Python标准库 bisect 中有二分查找函数,可以根据给定的有序数组和值直接求出二分查找的结果下标

from bisect import bisect_left, bisect_rightnums = [1,2,3,4,5,5,5,6,7,8]
# bisect_left() 返回列表中所有元素值等于所给值的元素的最小下标(左侧插入点)
index_1 = bisect_left(nums,5)  # index_1 = 4
# bisect_right() 返回列表中所有元素值等于所给值的元素的最大下标加一(右侧插入点)
index_2 = bisect_right(nums,5) # index_2 = 7

使用 bisect 库函数时应确保所提供的数组是有序数组

(二)二分法求最大解

border = 4.3
def check(num):if num <= border:return Trueelse:return False
# binary search
nums = [1,2,3,4,5,6,7,8,9]
left = 0
right = len(nums) - 1
while left < right:# 注意mid要加一,不然会出现死循环mid = (left + right + 1) >> 1if check(nums[mid]):# mid is validleft = midelse:# mid is not validright = mid-1
print(nums[left]) # output:4

(三)二分法求最小解

border = 6
def check(num):if num <= border:return Trueelse:return False# main part
nums = [1,2,3,4,5,6,7]
left = 0
right = len(nums) - 1
mid = (left + right) >> 1
while left < right:mid = (left + right) >> 1if check(nums[mid]):# mid is not validleft  = mid + 1else:right = mid
print(nums[left]) # output:7

二、应用实例

例题 1:求阶乘(蓝桥杯14届省赛)

题目描述:

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

输入格式:

输入一行,包含一个整数,表示k

输出格式:

输出一行,包含一个整数

提示:

对于 30 % 30\% 30% 的数据, 1 ≤ K ≤ 1 0 6 1 \leq K \leq 10^6 1K106,
对于 100 % 100\% 100% 的数据, 1 ≤ K ≤ 1 0 18 1 \leq K \leq 10^{18} 1K1018

代码示例:

# 暴力做法,只能通过40%的样例
# 0只能通过乘以10的倍数或5的倍数获得,因为2的倍数远多于5的倍数,所以不用考虑
# 100,1200之类的数需要特别处理
from sys import exitk = int(input())
if k < 0:print(-1)exit()
# 从5开始,以5为步长搜索5的倍数和10的倍数
n = 0 # 记录当前遍历到的因数
cur = 0 # 记录当前所得到的0的个数
while cur < k:n += 5# 先将n末尾所有的0转移到cur上temp = nwhile temp%10 == 0:temp //= 10cur += 1# 然后统计temp中5的个数while temp%5 == 0:temp //= 5cur += 1
if cur == k:print(n)
else:print(-1)

注意到对于一个给定的 n ! n! n!,末尾0的个数 = 从1到n各个数字的约数中5的个数 = k
k = n 5 1 + n 5 2 + n 5 3 + . . . k = \frac n {5^1} + \frac n {5^2} + \frac n {5^3} + ... k=51n+52n+53n+... 可以高效地求出指定n!的末尾0个数,所以可以使用二分法提高查找效率。

# Binary Search Optimize
# 注意到末尾0的个数随n的增大只会增大,不会减小,且结果的末尾0个数有大于等于k和小于k两种状态,所以可以使用二分法高效求解
def check(n):# 求出 n! 末尾0的个数res = 0# 这个过程的实质是求出构成阶乘的数字中所有5的倍数,25的倍数,125的倍数...while n:n //= 5res += nreturn res# binary search main part
k = int(input())
left = 1
right = 10**19
while left < right:mid = (left+right)//2if check(mid) < k:left = mid+1else:# mid 可能是正确答案,所以不能舍弃right = mid
# left = right
if check(left) == k:# 存在解print(left)
else:print(-1)

例题 2:k倍区间(蓝桥杯13届省赛)

题目链接:k倍区间

# 前缀和 + 取余 = 60%通过 + 40%超时
from copy import copy
n,k = map(int,input().split())
a = [int(i) for i in input().split()]
ans = 0
# 首先用原数组求单位长度区间的区间和是否满足条件
for i in range(n):if a[i] >= 0 and a[i] % k == 0:ans += 1
# 将a数组转化成前缀和数组再次求解
a = [0] + a
for i in range(1,n+1):a[i] += a[i-1]
# 因为我们只关心是否可以整除k,所以在计算前缀和的时候直接对k取余
# 余数相同的前缀和相减所得结果一定可以被 k 整除,但因为存在负数,所以还需要判断两个前缀和的大小关系
b = a.copy()
for i in range(1,n+1):b[i] = a[i]%k
for left in range(1,n):for right in range(left+1,n+1):if b[right] == b[left-1]:# 说明区间和是k的倍数,但可能是负数,所以还需要比较两端区间和的大小if a[left-1] <= a[right]:ans += 1
print(ans)
# 前缀和 + 取余 + 排序 + 二分
from bisect import bisect_right
from collections import defaultdictn,k = map(int,input().split())
a = [int(i) for i in input().split()]
total = 0  # 前缀和
ans = 0    # 答案
d = defaultdict(list)
d[0].append(0)# 注意一定要在离散化的同时进行二分搜索,因为各个前缀和的相对先后顺序不能被打乱
for i in range(n):total += a[i]# 计算出当前前缀和的余数temp = total % k# 确保余数均为正数以便操作(因为正负两种形式在事实上是等价的)if temp < 0:temp += k# 从当前元素的左侧所有和当前前缀和余数相等的元素中找出所有前缀和小于当前值的数量# 排序 + 二分 提高查找效率index = bisect_right(d[temp], total) # 比较的对象是各个区间的前缀和ans += index# 将新的前缀和插入有序数组,保证数组始终有序d[temp].insert(index, total)
print(ans)

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

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

相关文章

kafka客户端常用命令

kafka-topics.sh 相关的命令 Command Usage: create: enable rack strategy: kafka-topics.sh --create --topic --partitions <Integer: the number of partitions> --replication-factor <Integer: replication factor> --zookeeper <ZK_IP1:ZK_PORT,ZK_IP2:…

快速熟悉torchdiffeq用法,从数理逻辑到完整案例【第二部分】

本系列文章板块规划 提示&#xff1a;以下内容仅为个人学习感悟&#xff0c;无法保证完全的正确和权威&#xff0c;大家酌情食用谢谢。 第一部分 torchdiffeq背后的数理逻辑 第二部分 torchdiffeq的基本用法 第三部分 trochdiffeq的升级用法 第四部分 torchdifffeq的案例和代码…

C++11:function包装器

包装器&#xff0c;体现了C11中的封装性&#xff0c;包装器可以应用于&#xff1a;函数指针&#xff0c;仿函数&#xff0c;lambda 而包装器function的出现刚好也弥补了上述三种语法的不足之处 函数指针写起来较为复杂&#xff0c;而仿函数之间类型不同&#xff0c;lambda则在…

数学建模笔记(10)整数规划和0-1规划

前由 显然通关次数不能是小数&#xff0c;这就涉及到了整数问题。 定义 例题

最新mysql8.3 保姆级 主从复制搭建教程

mysql 主从复制搭建 服务器配置表 机器ip操作系统主机192.168.31.25华为openEuler-22.03-LTS-SP3从机192.168.31.184华为openEuler-22.03-LTS-SP3从机192.168.31.228华为openEuler-22.03-LTS-SP3 1、在3台机器上安装独立的 mysql 1.1 创建myql文件夹用来存放mysql包 mkdir…

python-可视化篇-turtle-画爱心

文章目录 原效果替换关键字5为8&#xff0c;看看效果改下颜色 原效果 import turtle as tt.color(red,pink) t.begin_fill() t.width(5) t.left(135) t.fd(100) t.right(180) t.circle(50,-180) t.left(90) t.circle(50,-180) t.right(180) t.fd(100) t.pu() t.goto(50,-30) t…

开发语言漫谈-C#

C#的#&#xff0c;字面上的意思就是&#xff0c;也就是把C再。微软只所以搞C#就是要抗衡Java。微软当时搞了个J&#xff0c;被Java告了&#xff0c;没办法了只能另取炉灶。从纯技术角度来看&#xff0c;C#设计非常优秀&#xff0c;可以覆盖所有领域&#xff0c;是几乎唯一的全栈…

【用户案例】太美医疗基于Apache DolphinScheduler的应用实践

大家好&#xff0c;我叫杨佳豪&#xff0c;来自于太美医疗。今天我为大家分享的是Apache DolphinScheduler在太美医疗的应用实践。今天的分享主要分为四个部分&#xff1a; 使用历程及选择理由稳定性的改造功能定制与自动化部署运维巡检与优化 使用历程及选择理由 公司介绍 …

.Net <% %>

<% %> 语法 : <% import namespace"system.data"%> 用来导入后台命名空间 指令用于指定当页和用户控件编译器处理 ASP.NET Web 窗体页 (.aspx) 和用户控件 (.ascx) 文件时所使用的设置。<% %> 语法 : <% name %> <% getstr() %&g…

修改el-button按钮背景色后,按钮失去了elementUI原有的hover和active的效果

应完整修改为&#xff1a; <el-button type"primary" icon"el-icon-plus" click"addUser">新增用户</el-button>.el-button--primary:not(.is-disabled) {background-color: #1174de;border-color: #1174de;&:hover {&:not…

尝试在手机上运行google 最新开源的gpt模型 gemma

Gemma介绍 Gemma简介 Gemma是谷歌于2024年2月21日发布的一系列轻量级、最先进的开放语言模型&#xff0c;使用了与创建Gemini模型相同的研究和技术。由Google DeepMind和Google其他团队共同开发。 Gemma提供两种尺寸的模型权重&#xff1a;2B和7B。每种尺寸都带有经过预训练&a…

【iOS ARKit】AR Quick Look 概述

为更好地传播共享 AR 体验&#xff0c;苹果公司引入了 AR Quick Look&#xff0c;并在iOS 12及以上版本系统中深度集成了 AR Quick Look&#xff0c;因此可以通过iMessage、Mail、Notes、 News、 Safari 和 Files 直接体验 AR&#xff0c;AR Quick Look提供了在 iPhone 和iPad …

排序算法,插入排序

插入排序是什么 插入排序&#xff08;Insertion Sort&#xff09;&#xff0c;一般也被称为直接插入排序。对于少量元素的排序&#xff0c;它是一个有效、简单的算法 其主要的实现思想是将数据按照一定的顺序一个一个的插入到有序的表中&#xff0c;最终得到的序列就是已经排…

使用opencv + ffmpeg 开发视频播放器Demo

使用opencv ffmpeg 开发视频播放器Demo #include <opencv2/opencv.hpp> #include <opencv2/highgui.hpp> #include <opencv2/videoio.hpp>extern "C" { #include <libavformat/avformat.h> #include <libavcodec/avcodec.h> #includ…

【LeetCode热题100】【二叉树】将有序数组转换为二叉搜索树

题目链接&#xff1a;108. 将有序数组转换为二叉搜索树 - 力扣&#xff08;LeetCode&#xff09; 取中间的数作为根节点&#xff0c;左边的数递归转换&#xff0c;右边的数递归转换 class Solution { public:TreeNode *sortedArrayToBST(vector<int> &nums) {retur…

通过 Spark SQL 和 DataFrames 与外部数据源交互

文章目录 前言Spark SQL 与 HiveUDF 通过 Spark SQL Shell, Beeline 和 Tableau 查询Spark SQL ShellBeelineTableau 外部数据源通过 JDBC 连接数据库PostgreSQLMySQL 高阶函数Explode 和 CollectUDF内置函数高阶函数 常用 DataFrames 和 Spark SQL 操作总结 前言 Spark 的数据…

隐私计算实训营第九讲-隐语多方安全计算在安全核对的行业实践

隐私计算实训营第九讲-隐语多方安全计算在安全核对的行业实践 文章目录 隐私计算实训营第九讲-隐语多方安全计算在安全核对的行业实践1.业务背景&#xff1a;安全核对产生的土壤1.1相关政策出台1.2 数据差异的来源 2.产品方案&#xff1a;从试点到规模化的路3.技术共建&#xf…

如何用MATLAB进行核密度估计

核密度估计&#xff08;Kernel Density Estimation&#xff0c;KDE&#xff09;是一种用于估计概率密度函数的非参数方法。以下是核密度估计的基本步骤和公式&#xff1a; 步骤&#xff1a; (1)数据预处理&#xff1a;在进行核密度估计之前&#xff0c;需要对原始数据进行清洗…

微信小程序报错——“errno“: 600001, “errMsg“: “request:fail -2:net::ERR_FAILED“

bug现象 微信小程序体验版和真机调试 进入小程序的时候接口就出现了这个报错 "errno": 600001, "errMsg": "request:fail -2:net::ERR_FAILED" 排查 检查是证书过期还是证书链不完整 证书的信任链完整问题&#xff0c;可以在 亚数信息-SSL/TLS安…

web安全学习笔记(8)

记一下第十二节课的内容。 一、PHP文件包含的四种方式 Include和Include_once 操作系统会读取包含的文件的内容&#xff0c;并将它插入主文件中&#xff0c;include方式的文件包含会在包含失败的情况下输出警告信息&#xff0c;而include_once方式会检查包含的文件是否已经被…