二分——acwing算法基础课笔记

发布时间 2023-12-08 20:09:46作者: zerocloud01

个人笔记,欢迎补充、指正。

此次完全以个人理解来写。

整数二分

 整数二分有两种,分别是找左边界和找右边界。

 寻找符合要求的左边界:绿色点

int bsearch_1(int l, int r)
{
    while (l < r)
    {
        int mid = l + r >> 1;//对应下界,最左
        if (check(mid)) r = mid;
        else l = mid + 1;
    }
    return l;
}

寻找符合要求的右边界:红色点

int bsearch_2(int l, int r)
{
    while (l < r)
    {
        int mid = l + r + 1 >> 1;对应上界,最右
        if (check(mid)) l = mid;
        else r = mid - 1;
    }
    return l;
}

和例题789. 数的范围 - AcWing题库结合看很容易理解

主要要确定check条件

此题

#include<bits/stdc++.h>

using namespace std;

void func(void);

const int N = 1e5 + 10;

int n,t,ans,stp;
int a[N];

int main(void)
{
    cin >> n >> t;
    for(int i=0;i<n;++i)    cin >> a[i];
    while(t--)
    {
        cin >> stp;
        int l = 0,r = n - 1;
        while(l < r)
        {
            int mid = l + r >> 1;
            if(a[mid] >= stp)    r = mid;
            else                l = mid + 1;
        }
        if(a[l] != stp)    cout << "-1 -1\n";
        else
        {
            cout << l << ' ';
            int l = 0,r = n - 1;
            while(l<r)
            {
                int mid = l + r + 1 >> 1;
                if(a[mid] <= stp)    l = mid;
                else                r = mid - 1;
            }
            cout << l << '\n';
        } 
    }
    return 0;
}

#include<bits/stdc++.h>

using namespace std;

void func(void);

const int N = 1e5 + 10;

int n,t,ans,stp;
int a[N];

int main(void)
{
    cin >> n >> t;
    for(int i=0;i<n;++i)    cin >> a[i];
    while(t--)
    {
        cin >> stp;
        int l = 0,r = n - 1;
        while(l < r)
        {
            int mid = l + r >> 1;
            if(a[mid] < stp)    l = mid + 1;
            else            r = mid;
        }
        if(stp != a[l])    cout << "-1 -1\n";
        else
        {
            cout << l << ' ';
            int l = 0,r = n - 1;
            while(l < r)
            {
            int mid = l + r + 1 >> 1;
            if(a[mid] > stp)    r = mid - 1;
            else            l = mid;
            }
            cout << l << '\n';
        }

    }
    return 0;
}

改变了check条件,但是都可ac

 

浮点数二分

浮点数二分就简单多了

double bsearch_3(double l, double r)
{
    const double eps = 1e-6;   // eps 表示精度,取决于题目对精度的要求
    while (r - l > eps)
    {
        double mid = (l + r) / 2;
        if (check(mid)) r = mid;
        else l = mid;
    }
    return l;
}