二分法通解

本文详细介绍了二分法在寻找满足特定条件的最小值、最大值以及精确值时的通用套路,并给出了具体的C++代码示例。通过二分法,可以高效地在有序数据中找到目标值。文章还通过实例解释了如何在查找递增数组中某个数的第一个和最后一个下标问题中应用二分法。此外,文章提到了使用二分法解决寻找数组中第K个最大元素的问题,以及在P2678 [NOIP2015 提高组] 跳石头问题中的应用,展示了如何判断满足条件的最大跳跃距离。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

# 二分法

## 套路

### 寻找满足条件的最小值(整数):

```c++
while (l <= r) 
{
    int mid = (l + r) / 2;
    //不同之处
    if (…… < / > 条件)
        l = mid + 1;
    else 
        r = mid - 1;
}
//l为要寻找的值
```

这是因为循环会在满足条件时减小右边界,不断向左移,直到找到满足条件的最小值

### 寻找满足条件的最大值(整数):

```c++
while (l <= r) 
{
    int mid = (l + r) / 2;
    //不同之处
    if (…… <= / >=条件)
        l = mid + 1;
    else 
        r = mid - 1;
}
//r为要寻找的值
```

这是因为循环会在满足条件时增大左边界,不断向右移,直到找到满足条件的最大值

### 寻找某个精确的值(非整数)

```c++
 while (r - l > 0.001) 
 { // 精度为小数点后两位
      double mid = (l + r) / 2;
      if (…… < / > 条件) //等于的话也无所谓
          r = mid;
      else 
          l = mid;
 }
 //mid为要寻找的值
```

左右差值小于 0.001 后输出mid值,此时 mid 值的精度必能满足要求:小数点后两位

此时不必再考虑到底是满足条件的最小值还是最大值

### 关键:

1.条件到底是什么

2.如何判断是否满足条件

3.不满足条件时,什么时候向左搜索,什么时候向右搜索

4.是要找满足条件的最小值还是最大值

### 举例:查找递增数组中某个数的第一个/最后一个下标

#### 题意:

输入 *n* 个不超过 109109 的单调不减的(就是后面的数字不小于前面的数字)非负整数 a1,a2,……,an,然后进行 *m* 次询问。对于每次询问,给出一个整数 *q*,要求输出这个数字在序列中第一次/最后一次出现的编号,如果没有找到的话输出 −1 。

#### 输入:

```c++
//找第一个
11 3
1 3 3 3 5 7 9 11 13 15 15
1 3 6
```

#### 输出:

```
1 2 -1 
```

#### 代码:

```c++
#include <vector>
#include <iostream>

int main() 
{
    int n, m;
    std::cin >> n >> m;
    std::vector<int> a(n), b(m);
    for (int i = 0; i < n; i++)
        std::cin >> a[i];
    for (int i = 0; i < m; i++)
        std::cin >> b[i];
    for (int x : b)
        std::cout << find_x(a, 0, n - 1, x) + 1 << ' ';
    std::cout << std::endl;<

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值