题解 | #机器人跳跃问题#

机器人跳跃问题

题目分析:

1)机器人有一定的能量,要想跳过前方的所有障碍,所需能量的最小值

2)能找到一种 (正/负)相关 的相关关系:

==》机器人所固有的能量越高,越能越过前方障碍

3)固有能量 和 能否越过障碍 之间的关系 的证明:

eg: 机器人名字(能量)、柱高:value

两个机器人:A(x) 、B(y) (x < y)

1) 遇到小于或等于自己能量的柱子:高能量机器人更具优势

value <= x < y:

对于 A:能量增幅(A_UP) 为 (x - value)

对于 B:能量增幅(B_UP) 为 (y - value)

明显:B_UP > A_UP

2) 遇到大于等于自己能量的柱子:高能量机器人更具优势

x < y <= value:

对于 A:能量减幅(A_DOWN) 为 (value - x)

对于 B:能量减幅(B_DOWN) 为 (value - y)

明显:A_DOWN > B_DOWN

3) 遇到 A 、B 机器人能量中间的柱子:高能量机器人更具优势

x < value < y:

对于 A:能量减幅(A_DOWN) 为 (value - x)

对于 B:能量增幅(B_UP) 为 (value - y)

明显:高能量机器人能量增加,低能量机器人能量减少

4)可以画二分图:

alt

代码:

时间复杂度:O(log2(max_value) * N)

额外空间复杂度:O(1)

#include<bits/stdc++.h>

using namespace std;

// 看看以当前能量:energy,能否越过前方所有柱子
bool f(int energy , const vector<int>& pillars , int maxx)
{
    for(const auto& e : pillars)
    {
        // 遇到小于等于自己能量的柱子:能量增加
        if(e<= energy)
        {
            energy += (energy - e);
        }
        // 遇到大于自己能量的柱子:能量减少
        else
        {
            energy -= (e - energy);
        }

        // 合理剪枝:当某阶段能量大于最高柱子时,一定能够能通过,不用再计算
        if(energy >= maxx)
        {
            return true;
        }

        // 合理剪枝的必要性:
        // eg: 1 1 1 ... 1 1   1 
        //     0 1 2 ... n n+1 n+2
        // 依次跳过这些柱子的能量变化(energy = 2):
        // energy + 1 + 2 + 4 + 8 + ... 
        // energy 以 2 的指数形式增加,不出几个柱子就会导致 energy 的值超过 long long 类型
        //所以一定要剪枝

        // 合理剪枝:当某阶段的能量小于0,一定不能够通过前方的所有柱子,不用再计算
        if(energy < 0)
        {
            return false;
        }

        // 如果能量:0 < energy <= max(pillars[i]) ,继续计算,正常跳下去
    }

    // 0 < energy <= max(pillars[i])
    // 通过了所有柱子,返回true
    return true;
}

int main()
{
    int n=0;
    vector<int> pillars;
    pillars.clear();
    scanf("%d" , &n);

    for(int i=0 ; i<n ; i++)
    {
        int x;
        scanf("%d" , &x);
        pillars.push_back(x);
    }

    // 能量值范围 [0 , max(pillars[i])]
    int maxx = pillars[0];
    for(const auto& e : pillars)
    {
        maxx = max(maxx , e);
    }

    int l=0 , r = maxx;
    int ans=0;

    // 进行二分
    while(l<=r)
    {
        // 防止溢出的一种写法:
        int mid = l + ((r-l)>>1);

        // 看看此时的 energy 能否通过前方所有柱子
        // 如果能,记录答案,并想能量值小的方向看,看看还有没有更小的能过通过所有柱子的答案
        if(f(mid , pillars , maxx))
        {
            ans = mid;
            r = mid - 1;
        }
        // 如果不能通过所有柱子,向能量稍微大一点的方向看
        else
        {
            l = mid+1;
        }
    }

    cout << ans << endl;

    return 0;
}
#二分模板##二分图##二分查找#
全部评论

相关推荐

哈哈哈,你是老六:百度去年裁员分评不好,赶紧弄点红包
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
正在热议
更多
# 一张图晒出你司的标语 #
4388次浏览 77人参与
# AI面会问哪些问题? #
28345次浏览 569人参与
# 厦门银行科技岗值不值得投 #
8117次浏览 188人参与
# 你的实习产出是真实的还是包装的? #
20448次浏览 343人参与
# 找AI工作可以去哪些公司? #
9446次浏览 251人参与
# 春招至今,你的战绩如何? #
66535次浏览 586人参与
# 开放七大实习专项,百度暑期实习值得冲吗 #
15435次浏览 223人参与
# 从事AI岗需要掌握哪些技术栈? #
9292次浏览 325人参与
# 中国电信笔试 #
32089次浏览 295人参与
# 你做过最难的笔试是哪家公司 #
34555次浏览 249人参与
# 投递几十家公司,到现在0offer,大家都一样吗 #
341004次浏览 2175人参与
# 哪些公司真双非友好? #
69720次浏览 289人参与
# 阿里笔试 #
179086次浏览 1318人参与
# 机械人避雷的岗位/公司 #
62710次浏览 393人参与
# 小马智行求职进展汇总 #
25141次浏览 80人参与
# 第一份工作一定要去大厂吗 #
14938次浏览 122人参与
# 金三银四,你的春招进行到哪个阶段了? #
22299次浏览 284人参与
# 担心入职之后被发现很菜怎么办 #
291391次浏览 1210人参与
# 为了减少AI幻觉,你注入过哪些设定? #
26288次浏览 310人参与
# 应届生第一份工资要多少合适 #
20697次浏览 86人参与
# HR最不可信的一句话是__ #
6374次浏览 114人参与
# 沪漂/北漂你觉得哪个更苦? #
10098次浏览 194人参与
牛客网
牛客网在线编程
牛客网题解
牛客企业服务