栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

AcWing算法基础课-二分

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

AcWing算法基础课-二分

二分

二分本质是用来查找满足某种性质的边界点
在给定区间内,能找到某种性质(check函数):

使得区间分为两部分
一部分满足,另外一部分不满足这种性质。

二分可以用来寻找这个性质的边界:满足某种性质的第一个元素;或者是满足某种性质的最后一个元素。
从而有两个不同模板

注意二分法一定能找到满足某种性质的边界点,但它不一定是你要找的目标,目标一不定在区间内,先写check函数,根据check函数更新区间,再判断用哪个模板。

二分模板一共有两个,分别适用于不同情况。
算法思路:
假设目标在闭区间[l,r]中,每次将区间长度缩小一半,当l=r时,我们就找到了目标值。
版本1

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

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;
}

版本2

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

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;
}
AcWing 789.数的范围

#include
using namespace std;
const int N=1e5+10;
int q[N];
int n,m;

int main()
{
    cin>>n>>m;
    for(int i=0;i>q[i];
    while(m--)
    {
        int k;
        cin>>k;
        int l=0,r=n-1;
        while(l>1;
            if(q[mid]>=k)
                r=mid;
            else
                l=mid+1;
        }
        if(q[l]!=k)
            cout<<-1<<' '<<-1<>1;
                if(q[mid]<=k)
                    l=mid;
                else
                    r=mid-1;
            }
            cout< 
AcWing 790.数的三次方根 

#include
using namespace std;
int main()
{
    double x;
    cin>>x;
    double l=-100,r=100;//根据题目范围 开三次方根 估计答案大概范围
    while(r-l>1e-8)
    {
        double mid=(l+r)/2;
        if(mid*mid*mid>=x)
            r=mid;
        else
            l=mid;
    }
    printf("%.6lfn",l);
    return 0;
}
浮点数的平方根
#include
using namespace std;
int main()
{
    double x;
    cin>>x;
    double l=0,r;
    //一个浮点数开平方,答案绝对值一定大于等于0,但是右边界根据输入浮点数是否大于1确定
    if(x>1)
        r=x;
    else
        r=1;
    while(r-l>1e-8)//经验: 保留6位小数 1e-8 4位 1e-6 多2
    {
        double mid=(l+r)/2;
        if(mid*mid>=x) r=mid;
        else l=mid;
    }
    printf("%.6lfn",l);
    return 0;
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/722374.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号