蓝桥杯二分查找

怎么一眼看出该题是否用二分呢?一般题目要求中出现以下关键词:最大值最小、最小值最大、满足条件的最小/最大、单调序列查找、分组、猜答案等类似词汇,直接选择二分。

一、万能通用模板

1.1查找某个值是否存在

python 复制代码
def binary_search(arr, target):
    l, r = 0, len(arr)-1
    while l <= r:
        mid = (l + r) // 2
        if arr[mid] == target:
            return mid   # 找到
        elif arr[mid] < target:
            l = mid + 1
        else:
            r = mid - 1
    return -1  # 没找到

1.2答案二分

适用于求最小满足条件的值

python 复制代码
def check(x):
    # 判断 x 是否满足题目条件
    return True/False

def find():
    l = 最小可能
    r = 最大可能
    ans = r
    while l <= r:
        mid = (l + r) // 2
        if check(mid):
            ans = mid
            r = mid - 1   # 想更小
        else:
            l = mid + 1   # 需要更大
    return ans

例题

问题描述

输入描述

输出描述

输出切出的正方形巧克力最大可能的边长。

输入输出示例

输入

2 10

6 5

5 6

输出

2

python 复制代码
# 变量:K位小朋友、N块巧克力、巧克力高为H、宽为W
# 要求:N块切出K块正方形大小相同的巧克力(当分出的巧克力块数大于等于小朋友人数满女足条件)
# 求满足条件的最大的边长 


# 分成边长为n的巧克力
def bian(n):
  # 未分前有n块巧克力
  ans=0
  for i in range(N):
    # 每块大巧克力分出的小巧克力的总和
    ans+=(H[i]//n)*(W[i]//n)
    # ans+=min(H[i]//n,W[i]//n)
  # 看是否满足分给的人数
  if ans>=K:
    return True
  return False


# 接取数据N、K
N,K=map(int,input().split())
H=[]
W=[]
# 分别借出数据H、W
for i in range(N):
  a=list(map(int,input().split()))
  H.append(a[0])
  W.append(a[1])
# 二分查找遍历边
# 左开右闭
left=1
right=100000
# 区间不为空
while left<right:
  # 这个中间值就是要分成的边长n
  mid=(left+right)//2
  # 如果可以分成mid块巧克力,目标是分的更大
  if bian(mid):
    left=mid+1# [mid+1,right)
  else:
    right=mid# [left,mid)
# 最终结果target[left,right)
print(left-1)

例题

输入描述

输出描述

输出一个整数表示答案。

输入输出样例

输入

10 3

5

2

10

输出

6

python 复制代码
# N个方格、K台机器人、第i台在第Ai个放个区域中

N,K=map(int,input().split())
# 首先塞一个0,数组遍历是从1开始的
A=[0]
for i in range(K):
  A.append(int(input()))
A.sort()

def check(mid):
  pos=0# 表示区域1~pos已被清扫,区域pos+1~n未被清扫
  # 遍历每一个机器人
  for i in range(1,K+1):
    # 花费这么多时间够不够
    time=mid
    # 1.往左清扫
    if pos<A[i]:
      time-=2*(A[i]-pos-1) # 往左清扫需要花费2*(a[i]-pos-1)
    # 如果时间小于 0,说明无法清扫完左边的区域,时间不够
    if time<0:
      return False
    # 2.往右清扫+每个机器人打扫完更新pos
    pos=A[i]+time//2# 如果还有剩余时间,往右清扫
  return pos>=N

left=1
right=2*N
# 左开右闭
while left<right:
  mid=(left+right)//2
  if check(mid):
    right=mid
  else:
    left=mid+1
# [left,right)
# [target)
print(right)
相关推荐
逻辑驱动的ken1 天前
Java高频面试考点场景题11
java·深度学习·面试·职场和发展·高效学习
Rabitebla1 天前
【数据结构】动态顺序表实现详解:从原理到接口设计(面试视角)
c语言·开发语言·数据结构·c++·面试·职场和发展
KobeSacre1 天前
leetcode 树
算法·leetcode·职场和发展
Engineer邓祥浩1 天前
LeetCode 热题 100 - 第1题:两数之和
算法·leetcode·职场和发展
算法即正义1 天前
知识竞赛音乐推荐:从开场抢答到颁奖环节的背景音乐选择指南
算法·职场和发展·学习方法
郝学胜-神的一滴1 天前
系统设计:新鲜事系统扩展与优化
java·python·职场和发展·php·软件工程·软件构建
穿条秋裤到处跑1 天前
每日一道leetcode(2026.04.23):等值距离和
算法·leetcode·职场和发展
_深海凉_1 天前
LeetCode热题100-88. 合并两个有序数组
算法·leetcode·职场和发展
人道领域1 天前
【LeetCode刷题日记】119.最长连续序列(字节面试题最新)
java·算法·leetcode·面试·职场和发展
chutao2 天前
EasyPDF 转图片(EasyPdf2Image)—— 本地安全实用的PDF与图片双向互转工具
安全·职场和发展·pdf·创业创新·学习方法