练13:二分法

news2024/12/20 11:28:29

欢迎大家订阅【蓝桥杯Python每日一练】 专栏,开启你的 Python数据结构与算法 学习之旅!

文章目录

  • 1 二分查找
  • 2 例题分析


1 二分查找

①定义
在计算机科学中,二分算法(Binary Search)是一种高效的查找算法,用于在一个已排序的数组中查找某个目标元素。二分算法的基本思想是通过将问题规模每次减半,来缩小查找范围,从而实现高效搜索。

②原理
二分查找算法基于分治思想。给定一个已排序的数组,二分算法通过不断将数组分为两部分,比较目标值与中间元素的关系,来确定目标值所在的范围。

③算法步骤

  1. 初始化边界:设定两个指针,leftright,分别指向数组的起始和结束位置。
  2. 计算中间位置:在每次查找中,计算中间位置 mid = (left + right) // 2
  3. 比较目标与中间值
    • 如果目标值等于中间元素 array[mid],则查找成功,返回该元素的索引。
    • 如果目标值小于中间元素,目标元素只能在左半部分,因此将右边界 right 更新为 mid - 1
    • 如果目标值大于中间元素,目标元素只能在右半部分,因此将左边界 left 更新为 mid + 1
  4. 终止条件:当 left > right 时,查找失败,目标元素不在数组中。

④时间复杂度分析

二分查找算法的时间复杂度为 O(log n),其中 n 是数组的元素个数。原因在于,每次查找时都会将搜索区间减半。因此,二分查找的效率非常高,尤其适用于大规模的数据集。

⑤空间复杂度分析

  • 非递归实现的空间复杂度为 O(1),因为只使用了常数级的额外空间。
  • 递归实现的空间复杂度为 O(log n),因为递归调用会占用栈空间。

⑤应用场景

二分查找算法在许多实际问题中都有广泛的应用,尤其是当数据集已经排好序时。常见的应用场景包括:

  1. 查找数据:二分查找常用于在已排序的数组中查找元素,尤其是当元素数量很大时,二分查找能够显著提高查找效率。
  2. 插入位置:在一些算法中,我们需要找出某个元素在一个已排序数组中的插入位置,这时二分查找是一种高效的方法。
  3. 区间问题:二分查找还可以用来解决一些特殊的区间问题,比如寻找满足某个条件的最小值或最大值。
  4. 搜索引擎与数据库:搜索引擎和数据库在对大量有序数据进行检索时,通常会用到二分查找。

在这里插入图片描述

2 例题分析

在这里插入图片描述

题目地址:https://www.lanqiao.cn/problems/99/learning/

样例输入

2 10
6 5
5 6

样例输出

2

【示例代码】

# 输入巧克力块的数量N和需要切出的块的数量K
N, K = map(int, input().split())  
a = []

for i in range(N):
    # 输入每个巧克力的长宽
    x, y = map(int, input().split())  
    # 将巧克力的长宽作为元组存储到列表a中
    a.append((x, y))  

# check函数:判断给定边长x时,是否能够切出至少K块巧克力小块
def check(x):
    # cnt表示当前边长x下,能够切出的块的总数
    cnt = 0  
    # 遍历每一块巧克力
    for H, W in a: 
         # 计算当前巧克力中可以切出多少个边长为x的小块 
        cnt += (H // x) * (W // x)  
    # 如果切出的块数大于等于K,则返回True,表示可能
    return cnt >= K  
    
# 二分查找边长x的最大值
left, right = 1, 100000  # 边长x的搜索范围,从1到100000
ans = 1  # 初始假定最小的有效边长为1

while left <= right:
    mid = (left + right) // 2  # 取当前搜索区间的中点
    if check(mid):  # 如果可以切出至少K块小块
        ans = mid  # 记录当前中点作为可能的答案
        # 尝试寻找更大的边长,调整搜索区间为[mid+1, right]
        left = mid + 1  
    else:
        # 否则尝试更小的边长,调整搜索区间为[left, mid-1]
        right = mid - 1  
print(ans)  # 输出最大边长

【执行流程】

①初始输入

N, K = map(int, input().split())  # 输入巧克力块的数量N和需要切出的块的数量K
a = []

for i in range(N):
    # 输入每个巧克力的长宽
    x, y = map(int, input().split())  
    # 将巧克力的长宽作为元组存储到列表a中
    a.append((x, y))
  • 输入的 2 10 解析为 N = 2K = 10,表示有 2 块巧克力,目标是切出 10 块小巧克力。
  • 接下来,输入两行表示巧克力的尺寸:6 55 6
  • a 列表最终存储为 [(6, 5), (5, 6)],即两块巧克力的尺寸。

②定义 check(x) 函数

def check(x):
    # cnt表示当前边长x下,能够切出的块的总数
    cnt = 0  
    # 遍历每一块巧克力
    for H, W in a: 
         # 计算当前巧克力中可以切出多少个边长为x的小块 
        cnt += (H // x) * (W // x)  
    # 如果切出的块数大于等于K,则返回True,表示可能
    return cnt >= K
  • check(x) 的作用是,给定边长 x,判断是否能够切出至少 K 块小巧克力。
  • 对于每一块巧克力 (H, W),计算在该巧克力中能够切出的边长为 x 的小块数目为 (H // x) * (W // x),即在高度和宽度上都切割出多少个小块。
  • 最后,返回 cnt >= K,表示切出的块数是否达到或超过了 K

③二分查找最大边长

left, right = 1, 100000  # 边长x的搜索范围,从1到100000
ans = 1  # 初始假定最小的有效边长为1

while left <= right:
    mid = (left + right) // 2  # 取当前搜索区间的中点
    if check(mid):  # 如果可以切出至少K块小块
        ans = mid  # 记录当前中点作为可能的答案
        # 尝试寻找更大的边长,调整搜索区间为[mid+1, right]
        left = mid + 1  
    else:
        # 否则尝试更小的边长,调整搜索区间为[left, mid-1]
        right = mid - 1  
print(ans)  # 输出最大边长
  • 设定初始的搜索范围为 left = 1right = 100000,表示我们假定边长 x 可能的最大值为 100000
  • 使用二分查找逐步缩小搜索范围来找到能切出至少 K 块小巧克力的最大边长 x

【执行二分查找过程】

初始区间 [left=1, right=100000]

第一次循环

  • 计算中点:mid = (1 + 100000) // 2 = 50000
  • 调用 check(50000)
    • 对于第一块巧克力 (6, 5)50000 边长无法切割出任何小块(6 // 50000 = 05 // 50000 = 0),所以结果为 0 块。
    • 对于第二块巧克力 (5, 6),同样,50000 边长无法切割出任何小块(5 // 50000 = 06 // 50000 = 0),所以结果为 0 块。
    • 总共切出的块数为 0check(50000) 返回 False,因此调整搜索区间为 [1, 49999]

第二次循环

  • 计算中点:mid = (1 + 49999) // 2 = 25000

  • 调用 check(25000)

    • 对于第一块巧克力 (6, 5)25000 边长无法切割出任何小块(6 // 25000 = 05 // 25000 = 0),所以结果为 0 块。
    • 对于第二块巧克力 (5, 6),同样,25000 边长无法切割出任何小块(5 // 25000 = 06 // 25000 = 0),所以结果为 0 块。
    • 总共切出的块数为 0check(25000) 返回 False,因此调整搜索区间为 [1, 24999]
  • 继续减小搜索区间:直到找到一个合适的边长。

终止条件与最终结果

最终,通过多次二分查找,我们最终会找到 x = 2 是最大边长,能够切出至少 K = 10 块小巧克力。具体的结果是:

  • 对于 x = 2,第一块巧克力 (6, 5) 可以切出 6 // 2 = 3 行,5 // 2 = 2 列,总共能切出 3 * 2 = 6 块。
  • 对于 x = 2,第二块巧克力 (5, 6) 可以切出 5 // 2 = 2 行,6 // 2 = 3 列,总共能切出 2 * 3 = 6 块。
  • 总共切出的块数是 6 + 6 = 12 块,满足 K = 10,因此 check(2) 返回 True,最终输出 2

④最终输出

2

【运行结果】
在这里插入图片描述

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

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

相关文章

Android Studio更改项目使用的JDK

一、吐槽 过去&#xff0c;在安卓项目中配置JDK和Gradle的过程非常直观&#xff0c;只需要进入Android Studio的File菜单中的Project Structure即可进行设置&#xff0c;十分方便。 原本可以在这修改JDK: 但大家都知道&#xff0c;Android Studio的狗屎性能&#xff0c;再加…

基于ST STM32MP257FAK3的MP2控制器之工业PLC 方案

简介 1.可编程逻辑控制器&#xff08;PLC&#xff09;是种专门为在工业环境下应用而设计的数字运算操作电子系统。它采用一种可编程的存储器&#xff0c;在其内部存储执行逻辑运算、顺序控制、定时、计数和算术运算等操作的指令&#xff0c;通过数字式或模拟式的输入输出来控制…

唯品会Android面试题及参考答案

HTTP 和 HTTPS 的区别是什么?你的项目使用的是 HTTP 还是 HTTPS? HTTP 和 HTTPS 主要有以下区别。 首先是安全性。HTTP 是超文本传输协议,数据传输是明文的,这意味着在数据传输过程中,信息很容易被窃取或者篡改。比如,在一个不安全的网络环境下,黑客可以通过网络嗅探工具…

黑马Java面试教程_P2_Redis

系列博客目录 文章目录 系列博客目录1前言2 使用场景面试官提问1&#xff1a;我看你做的项目中&#xff0c;都用到了redis&#xff0c;你在最近的项目中哪些场景使用了redis呢?面试官会接着问你1.1&#xff1a;如果发生了缓存穿透、击穿、雪崩&#xff0c;该如何解决?2.1缓存…

Python如何正确解决reCaptcha验证码(9)

前言 本文是该专栏的第73篇,后面会持续分享python爬虫干货知识,记得关注。 我们在处理某些国内外平台项目的时候,相信很多同学或多或少都见过,如下图所示的reCaptcha验证码。 而本文,笔者将重点来介绍在实战项目中,遇到上述中的“reCaptcha验证码”,如何正确去处理并解…

Unity3D仿星露谷物语开发5之角色单例模式

1、目的 使用单例模式创建角色对象&#xff0c;保证整个游戏中只有一个角色&#xff0c;并且让游戏对象具有全局可访问性。 2、流程 &#xff08;1&#xff09;创建SingletonMonobehaviour脚本 Assets下创建Scripts目录用于存放所有的脚本&#xff0c;再创建Misk子目录&…

控制表格向上滚动距离最佳实践(以Element ui为例)

前言 在web开发中&#xff0c;有些时候使用的组件库的表格不支持滚动的属性或方法。这个时候我们就要自己去实现这一功能。在Element Plus里&#xff0c;组件库已经具备了支持滚动表格的属性或方法&#xff0c;但是在支持vue2的element ui里&#xff0c;Table组件本身不提供直…

ubuntu16.04ros-用海龟机器人仿真循线系统

下载安装sudo apt-get install ros-kinetic-turtlebot ros-kinetic-turtlebot-apps ros-kinetic-turtlebot-interactions ros-kinetic-turtlebot-simulator ros-kinetic-kobuki-ftdi sudo apt-get install ros-kinetic-rocon-*echo "source /opt/ros/kinetic/setup.bash…

6.3 Postman环境变量与全局变量

欢迎大家订阅【软件测试】 专栏&#xff0c;开启你的软件测试学习之旅&#xff01; 文章目录 前言1 变量类型2 环境变量&#xff08;Environment Variables&#xff09;3 全局变量&#xff08;Global Variables&#xff09;4 环境变量与全局变量的区别 前言 为了提高测试的灵活…

概率论得学习和整理27:关于离散的数组 随机变量数组的均值,方差的求法3种公式,思考和细节。

目录 1 例子1&#xff1a;最典型的&#xff0c;最简单的数组的均值&#xff0c;方差的求法 2 例子1的问题&#xff1a;例子1只是1个特例&#xff0c;而不是普遍情况。 2.1 例子1各种默认假设&#xff0c;导致了求均值和方差的特殊性&#xff0c;特别简单。 2.2 我觉得 加权…

模型 QFD(质量功能展开/质量屋)

系列文章 分享 模型&#xff0c;了解更多&#x1f449; 模型_思维模型目录。将客户需求转化为产品设计。 1 模型 QFD&#xff08;质量功能展开&#xff09;的应用 1.1 电信服务及网络维护过程质量改进QFD应用案例 背景介绍&#xff1a; 随着中国加入WTO和国家对电信管制的普遍…

ECharts柱状图-柱图38,附视频讲解与代码下载

引言&#xff1a; 在数据可视化的世界里&#xff0c;ECharts凭借其丰富的图表类型和强大的配置能力&#xff0c;成为了众多开发者的首选。今天&#xff0c;我将带大家一起实现一个柱状图图表&#xff0c;通过该图表我们可以直观地展示和分析数据。此外&#xff0c;我还将提供…

Android XR 应用程序开发 | 从 Unity 6 开发准备到应用程序构建的步骤

在本文中 将解释为 Android XR 开发做准备的步骤&#xff0c;从下载 Unity 6 到项目和构建。 &#xff08;这次我将解释使用 Mac 的设置&#xff0c;但 Windows 的过程通常相同。 &#xff09; 如果您的许可证是 Personal&#xff0c;您仍然可以使用 Unity 开发 Android XR 应…

204页PPT金税四期监管要求与最新政策及风险防范-培训课件

这份资料是关于金税四期监管要求、最新政策及风险防范的培训课件&#xff0c;包含204页PPT内容。核心内容涉及金税四期的发展历程、与金税三期的主要变化、指挥决策系统、税务风险预警指标、重点监控行为、税务稽查重点领域、避税方法及处罚、以及企业自查和税务风险管控原理。…

比较器基本玩法

1 红外水龙头 1 比较器的工作特性 2 红外接收二极管的工作原理 1 红外发射二极管和红外接收二极管 2 红外接收二极管接收到&#xff0c;产生的电流是100uA&#xff0c;即电压等于4V 3 自动出水水龙头 4 比较器内部结构 1 有一些比较器需要加上拉电阻&#xff08;类似开漏输…

基于Qt的登陆界面设计

目标 自由发挥登录界面的应用场景&#xff0c;实现一个登录窗口的界面。 要求&#xff1a;每行代码都要有注释 代码 // 设置窗口大小为600x400像素 this->resize(600,400); // 设置窗口标题为"TheWitcher 巫师3&#xff1a;狂猎" this->setWindowTitle(&qu…

数据库建模工具 PDManer

数据库建模工具 PDManer 1.PDManer简介2.PDManer使用 1.PDManer简介 PDManer&#xff08;元数建模&#xff09;是一款功能强大且易于使用的开源数据库建模工具。它不仅支持多种常见数据库&#xff0c;如MySQL、PostgreSQL、Oracle、SQL Server等&#xff0c;还特别支持国产数据…

排序算法深度好文(图解 + 代码解析 + 误区 QA )——学排序看这一篇就够了!!!

排序算法 一、概述 1. 内部排序 (1) 冒泡排序 (2) 选择排序 a. 简单选择排序 b. 堆排序 (3) 插入排序 a. 直接插入排序 b. 希尔排序 (4) 快速排序 快速排序 hoare 版本 快速排序挖坑法 优化一随机化快速排序 优化二中位数三分法 (5) 归并排序 (6) 基数排序 2. …

【C语言程序设计——基础】顺序结构程序设计(头歌实践教学平台习题)【合集】

目录&#x1f60b; <第1关&#xff1a;顺序结构的应用> 任务描述 相关知识 编程要求 测试说明 我的通关代码: 测试结果&#xff1a; <第2关&#xff1a;交换变量值> 任务描述 相关知识 编程要求 测试说明 我的通关代码: 测试结果&#xff1a; <第…

git stash 的文件如何找回

在Git中&#xff0c;如果你使用了git stash命令来保存你的工作进度&#xff0c;但之后想要找回这些被stash的文件&#xff0c;你可以按照以下步骤进行操作&#xff1a; 1. 查看stash列表 首先&#xff0c;使用git stash list命令来查看当前保存的所有stash记录。这个命令会列出…