c++ 算法之二分答案详解

二分答案 是 c++ 之中一个简单而重要的算法,每一个 OIer 必备的基础算法,你知道它究竟是什么吗?

目录

一、简介

        1.定义

        2.时间复杂度

二、核心代码

 三、例题

        1.跳石头

                1.题目描述

                2.解法

        2.进击的奶牛

                1.题目描述

                2.思路

一、简介

        1.定义

    二分答案是一种二分搜索,二分搜索(英语:binary search),也称折半搜索(英语:half-interval search)、对数搜索(英语:logarithmic search),是一种在有序数组中查找某一特定元素的搜索算法。那么二分答案顾名思义即是在一个特定区间内搜索答案的算法,二分答案一般求一个最大值的最小值,或最小值的最大值,比如求小于 2 的最大正整数(这种题当然不必二分答案)。且有一个最大边界值和最小边界值(前面的例子若去掉“正”字,将无法二分答案,因为小于2的整数集合是无限集合)。二分答案要求必须有单调性,一会符合条件,一会不符合只能枚举

        2.时间复杂度

    二分答案,顾名思义采用了分治思想,不断缩小搜索范围,最后求出答案,所以时间复杂度自然是对数阶的,由于是二分,所以时间复杂度是 O(k log n) 的,k 是什么,请往下看······

二、核心代码

int l = 1,r = n,ans; // l 是最小值,r 是最大值,ans 是答案。
while(l<=r)
{
    int mid = (l + r) / 2; // mid 是最大范围和最小范围的中间值。
    if(check(mid)) // 检查 mid 是否符合条件。
    {
        r = mid - 1;
        ans = mid;
        // mid 是符合条件的,继续搜索有没有比它还小的符合条件的值。
    }
    else l = mid + 1;
    // mid 不符合条件,所以 mid 和 mid 以下的值都不行。
}
cout << ans;

    仔细读几遍代码,可以发现,k 就是 check 的时间复杂度啦!

 三、例题

        1.跳石头

                1.题目描述

    一年一度的“跳石头”比赛又要开始了!

    这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石。组委会已经选择好了两块岩石作为比赛起点和终点。在起点和终点之间,有 N 块岩石(不含起点和终点的岩石)。在比赛过程中,选手们将从起点出发,每一步跳向相邻的岩石,直至到达终点。

    为了提高比赛难度,组委会计划移走一些岩石,使得选手们在比赛过程中的最短跳跃距离尽可能长。由于预算限制,组委会至多从起点和终点之间移走 M 块岩石(不能移走起点和终点的岩石)。

                2.解法

    自然是二分若求最短跳跃距离啦,但“最短跳跃距离尽可能长”的话 while 循环里的代码就不能像刚才那样了,恰恰相反:

int l = 1,r = n,ans;
while(l<=r)
{
    int mid = (l + r) / 2;
    if(check(mid))
    {
        l = mid + 1;
        ans = mid;
    }
    else r = mid - 1;
}
cout << ans;

     check 函数里遍历所有石头,若两石头之间距离不够长就扩大,最后若扩大次数小于等于 m 返回 true 。

bool check(int x)
{
    int ans = 0,temp = a[0];
    for(int i = 1;i <= n + 1;i ++){
        if(a[i] - temp < s){
            ans ++;
        }
        else{
            temp = a[i];
        }
    }
    if(ans > m)  return false;
    return true;
}

    为什么 i 要遍历到 n+1 ,因为“(不含起点和终点的岩石)”,说明重点会有石头。为什么 “return true” 前面不用加 “else” 因为 “return false” 函数就结束了。

        2.进击的奶牛

                1.题目描述

    Farmer John 建造了一个有 N 个隔间的牛棚,这些隔间分布在一条直线上。

他的 C 头牛不满于隔间的位置分布,它们为牛棚里其他的牛的存在而愤怒。为了防止牛之间的互相打斗,Farmer John 想把这些牛安置在指定的隔间,所有牛中相邻两头的最近距离越大越好。那么,这个最大的最近距离是多少呢?

                2.思路

    1.一定要排序 !!!

    2.二分最大距离

你学会了吗?

  • 17
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值