小工具知识网

当前位置: 首页 > 行业知识 > 算法复习之二分【备战蓝桥杯】

行业知识

算法复习之二分【备战蓝桥杯】

2026-11-04 15:11:09 来源:互联网转载

二分���板一共有两个,分别适用于不同情况。

算法思路:假设目标值在闭区间[l, r]中, 每次将区间长度缩小一半,当l = r时,我们就找到了目标值。

版本一

当我们将区间[l, r]划分成[l, mid]和[mid + 1, r]时,其更新操作是r = mid或者l = mid + 1;计算mid时不需要加1。

int bsearch_1(int l, int r){    while (l > 1;        if (check(mid)) r = mid;        else l = mid + 1;    }    return l;}

版本二

当我们将区间[l, r]划分成[l, mid - 1]和[mid, r]时,其更新操作是r = mid - 1或者l = mid;此时为了防止***循环,计算mid时需要加1。

int bsearch_2(int l, int r){    while (l > 1;        if (check(mid)) l = mid;        else r = mid - 1;    }    return l;}

总结

假设有一个总区间,经由我们的 check 函数判断后,可分成两部分,

这边以o作 true,…作 false 示意较好识别

如果我们的目标是下面这个v,那麽就必须使用模板 1

…vooooooooo

假设经由 check 划分后,整个区间的属性与目标v如下,则我们必须使用模板 2

oooooooov…

所以下次可以观察 check 属性再与模板1 or 2 互相搭配就不会写错啦

练习题

503. 借教室

#include #include #include using namespace std;typedef long long LL;const int N = 1000010;int n, m;int w[N];int d[N], l[N], r[N];LL b[N];bool check(int mid) {    memset(b, 0, sizeof b);    for (int i = 1; i = k) return true;    }    return false;}int bsearch(){    int l = 1, r = 1e5 + 10;    while (l > 1;        if (check(mid)) l = mid;        else r = mid - 1;    }}int main(){    scanf("%d%d", &n, &k);    for (int i = 0; i  

4956. 冶炼金属

#include #include #include using namespace std;const int N = 10010;int n;int a[N], b[N];bool check_1(int mid) {    // 找最小的 那么其他部分都得满足小于等于b[i]    for (int i = 0; i  b[i]) return false;    return true;}bool check_2(int mid) {    // 找最大得 那么其他部分都得满足大于等于b[i]    for (int i = 0; i > 1;        if (check_1(mid)) r = mid;        else l = mid + 1;    }    printf("%d ", l);    r = 1e9 + 1;    while (l > 1;        if (check_2(mid)) l = mid;        else r = mid - 1;    }    printf("%d", l);    return 0;}作者:大四萌新.链接:https://www.acwing.com/activity/content/code/content/7899986/来源:AcWing著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

上一篇:怎么修改运营者?

下一篇:怎么蹲点进服务器里面?