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

【AcWing - 算法基础】基础算法之二分算法

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

【AcWing - 算法基础】基础算法之二分算法

二分
    • Cpp二分查找算法模板
      • 789. 数的范围
      • 790. 数的三次方根
    • Cpp二分查找

Cpp二分查找算法模板

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

版本1

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

C++ 代码模板:

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

Go语言 代码模板:

func bsearch_1(l, r int) int {
    for l < r {
        mid := ( l + r + 1 ) >> 1 
        if check(mid) {         
            l = mid
        }else{
            r = mid - 1
        }
    }
    return l
}

版本2

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

C++ 代码模板:

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

Go语言 代码模板:

func bsearch_2(l, r int) int {
    for l < r {
        mid := ( l + r ) >> 1 
        if check(mid) {         
            r = mid
        }else{
            l = mid + 1
        }
    }
    return l
}

使用方式: 一般使用版本2,若版本2出现TLE那就换版本1 就好啦.

789. 数的范围

给定一个按照升序排列的长度为 n n n的整数数组,以及 q q q个查询。

对于每个查询,返回一个元素 k k k的起始位置和终止位置(位置从 0 0 0开始计数。

如果数组中不存在该元素,则返回 -1 -1。

输入格式

第一行包含整数 n
和 q
,表示数组长度和询问个数。

第二行包含 n
个整数(均在 1∼10000
范围内),表示完整数组。

接下来 q
行,每行包含一个整数 k
,表示一个询问元素。

输出格式

共 q
行,每行包含两个整数,表示所求元素的起始位置和终止位置。

如果数组中不存在该元素,则返回 -1 -1。

数据范围

  • 1≤n≤100000

  • 1≤q≤10000

  • 1≤k≤10000

Cpp二分查找

#include 

using namespace std;

const int N = 100010;

int n, m;
int q[N];

int main()
{
    scanf("%d%d", &n, &m);
    for (int i = 0; i < n; i ++ ) scanf("%d", &q[i]);

    while (m -- )
    {
        int x;
        scanf("%d", &x);

        int l = 0, r = n - 1;
        while (l < r)
        {
            int mid = l + r >> 1;
            if (q[mid] >= x) r = mid;
            else l = mid + 1;
        }

        if (q[l] != x) cout << "-1 -1" << endl;
        else
        {
            cout << l << ' ';

            int l = 0, r = n - 1;
            while (l < r)
            {
                int mid = l + r + 1 >> 1;
                if (q[mid] <= x) l = mid;
                else r = mid - 1;
            }

            cout << l << endl;
        }
    }

    return 0;
}
790. 数的三次方根

给定一个浮点数 n
,求它的三次方根。

输入格式

共一行,包含一个浮点数 n

输出格式

共一行,包含一个浮点数,表示问题的解。

注意,结果保留 6
位小数。

数据范围

−10000≤n≤10000

输入样例:

1000.00

输出样例:

10.000000
Cpp二分查找
#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("%.6lf",r);
    return 0;
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/443661.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

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

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