蓝桥杯二分查找

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

一、万能通用模板

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)
相关推荐
炜宏资料库34 分钟前
国网最新:电力市场结算规则解读
职场和发展
洛水水1 小时前
【力扣100题】46.单词拆分
算法·leetcode·职场和发展
洛水水4 小时前
【力扣100题】45.零钱兑换
算法·leetcode·职场和发展
芝士爱知识a4 小时前
2026 年教资面试考前急救软件推荐:基于智蛙面试app的技术评测
面试·职场和发展·智蛙面试·教资面试软件·ai模拟面试·教资考前急救·多模态大模型应用
帅次5 小时前
Android 高级工程师面试参考答案:项目经历、自我介绍与实战案例表达
android·面试·职场和发展
洛水水5 小时前
【力扣100题】47.最长递增子序列
算法·leetcode·职场和发展
木子墨5166 小时前
系统设计面试 | 实现一个限流器:滑动窗口 → 令牌桶 → 漏桶
java·开发语言·数据结构·数据库·面试·职场和发展
_日拱一卒7 小时前
LeetCode:199二叉树的右视图
算法·leetcode·职场和发展
鱼子星_7 小时前
【数据结构与算法】OJ题目详解(一)-单链表:从易到难的面试OJ题目
c语言·数据结构·算法·链表·面试·职场和发展
凌波粒8 小时前
LeetCode--二叉树层序遍历实战指南
算法·leetcode·职场和发展