二分(整数二分,浮点数二分模板)

本文详细介绍了整数和小数的二分查找算法,以及lower_bound和upper_bound在有序数据结构中的应用,通过实例演示加深理解。

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


二分写起来这是让人头疼的东西

一、整数二分

int bs1(int l, int r) {
    while(l < r) {
        int mid = (l + r) >> 1;
        //如果满足某种性质,答案在左半边
        if(check(mid)) r = mid;
        else l = mid + 1;
    }
    return l;
}

int bs2(int l,int r){
    while(l<r){
        int mid = (l+r+1)>>1;
        //如果满足某种性质,答案在右半边
        if(check(mid)) l = mid;
        else r = mid -1;
    }
    return l;
}

emm…来一道题记录一下,帮助自己理解

链接: 传送门.
在这里插入图片描述

既然是找到第一次出现的位置,答案严格在左半边,我们选择使用第一个模板,while(a[mid]<=x) r = mid; 一直往左找对吧

void solve() {
    _read(n), _read(m);
    _rep(i, 1, n) _read(a[i]);


    while(m--) {
        int x;
        _read(x);
        int l = 1, r = n;
        while(l < r) {
            int mid = (l + r) >> 1;
            if(a[mid] >= x) r = mid;
            else l = mid + 1;
        }
        //还得判断一下,万一超了边界
        if(a[r] == x) cout <<r << " ";
        else cout << "-1 ";
    }
}

二、小数二分

double bs3(double l, double r) {
    while(r - l > 精度) {
        double mid = (l + r) >> 1;
        if(check(mid)) r = mid;
        else l = mid;
    }
    return l;
}

链接: 传送门.
在这里插入图片描述

int a, b, m;
int check(double mid) {
    double s = a;
    _rep(i, 1, m) {
        s = s + s * mid - b;
    }
    if(s >= 0) return 1;
    else return 0;
}
void solve() {
    _read(a), _read(b), _read(m);
    double l = 0, r = 500;
    while(r - l > 1e-5) {
        double mid = (l + r) / 2;
        if(check(mid)) r = mid;
        else l = mid;
    }
    printf("%.1f", l * 100);
}

三、lower_bound()和upper_bound()

lower_bound:返回迭代器,指向大于等于key的第一个值的位置
upper_bound:返回迭代器,指向大于key的第一个值的位置

数组中使用:

int a[]={1,2,3,4,5,7,8,9}; //一定要是有序数组
printf("%d",lower_bound(a,a+8,6)-a); 
/*
output:
5
*/

vector中使用:

vector<int> a; //1 2 3 4 5 6 7 8 9
printf("%d",lower_bound(A.begin() , A.end() , 6)-A.begin());
/*
output:
5
*/

map中使用:

map<int,string>::iterator p1,p2;
p1 = mp.lower_bound(3);
p2 = mp.upper_bound(3);
cout<<"lower_bound"<<p1->first<<"=>"<<p1->second.c_str()<<endl;
cout<<"upper_bound"<<p2->first<<"=>"<<p2->second.c_str()<<endl;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值