二分-字节跳动笔试题-机器人跳跃问题

二分-字节跳动笔试题- 机器人跳跃问题

题目:
机器人正在玩一个古老的基于DOS的游戏。

游戏中有N+1座建筑——从0到N编号,从左到右排列。

编号为0的建筑高度为0个单位,编号为 i 的建筑高度为H(i)个单位。

起初,机器人在编号为0的建筑处。

每一步,它跳到下一个(右边)建筑。

假设机器人在第k个建筑,且它现在的能量值是E,下一步它将跳到第k+1个建筑。

如果H(k+1)>E,那么机器人就失去H(k+1)-E的能量值,否则它将得到E-H(k+1)的能量值。

游戏目标是到达第N个建筑,在这个过程中能量值不能为负数个单位。

现在的问题是机器人以多少能量值开始游戏,才可以保证成功完成游戏?

输入格式
第一行输入整数N。

第二行是N个空格分隔的整数,H(1),H(2),…,H(N)代表建筑物的高度。

输出格式
输出一个整数,表示所需的最少单位的初始能量值。

数据范围
1≤N,H(i)≤105,

输入样例1:
5
3 4 3 2 4
输出样例1:
4
输入样例2:
3
4 4 4
输出样例2:
4
输入样例3:
3
1 6 4
输出样例3:
3

时/空限制:3s / 64MB
来源:今日头条2019,笔试题

题意:
输 入 建 筑 数 量 N , 输 入 N 个 建 筑 的 高 度 H i , i ∈ [ 1 , N ] 。 输入建筑数量N,\\输入N个建筑的高度H_i,i∈[1,N]。 N,NHii[1,N]

机 器 人 站 在 起 始 位 置 0 处 具 有 能 量 E 0 , 有 N 个 建 筑 , 从 低 处 往 高 处 跳 需 要 消 耗 能 量 , 从 高 处 往 低 处 跳 能 量 会 增 加 , 要 求 能 够 跳 跃 N 个 建 筑 的 最 低 初 始 能 量 E 0 m i n 。 机器人站在起始位置0处具有能量E_0,有N个建筑,从低处往高处跳需要消耗能量,\\从高处往低处跳能量会增加,要求能够跳跃N个建筑的最低初始能量E_{0min}。 0E0NNE0min

设 机 器 人 在 第 i 个 位 置 处 的 能 量 为 E i , 由 题 意 : 当 后 一 个 建 筑 的 高 度 H i + 1 > E i 时 , 机 器 人 将 失 去 H i − 1 − E i 的 能 量 , 那 么 E i + 1 = E i − ( H i + 1 − E i ) = 2 E i − H i + 1 。 当 后 一 个 建 筑 的 高 度 H i + 1 < E i 时 , 机 器 人 将 得 到 E i − H i − 1 的 能 量 , 那 么 E i + 1 = E i + ( E i − H i − 1 ) = 2 E i − H i + 1 。 设机器人在第i个位置处的能量为E_i,由题意:\\当后一个建筑的高度H_{i+1}>E_i时,机器人将失去H_{i-1}-E_i的能量,\\那么E_{i+1}=E_i-(H_{i+1}-E_i)=2E_i-H_{i+1}。\\当后一个建筑的高度H_{i+1}<E_i时,机器人将得到E_i-H_{i-1}的能量,\\那么E_{i+1}=E_i+(E_i-H_{i-1})=2E_i-H_{i+1}。 iEi,:Hi+1>EiHi1EiEi+1=Ei(Hi+1Ei)=2EiHi+1Hi+1<EiEiHi1Ei+1=Ei+(EiHi1)=2EiHi+1

于 是 得 到 E i 的 递 推 式 E i = 2 E i − 1 − H i , i ∈ [ 1 , N ] 。 于是得到E_i的递推式E_i=2E_{i-1}-H_i,i∈[1,N]。 EiEi=2Ei1Hi,i[1,N]

显 然 , E i 越 大 , 就 越 可 能 满 足 题 意 , 当 E i > = E m i n 时 满 足 题 意 , 当 E i < E m i n 时 不 满 足 题 意 , 答 案 满 足 二 段 性 ( 单 调 性 ) , 所 以 考 虑 二 分 得 到 答 案 。 显然,E_i越大,就越可能满足题意,\\当E_i>=E_{min}时满足题意,当E_i<E_{min}时不满足题意,\\答案满足二段性(单调性),所以考虑二分得到答案。 EiEi>=EminEi<Emin(),

但 由 于 E i 是 呈 指 数 级 增 长 的 , 而 i ∈ [ 1 , 100000 ] , 必 然 会 出 现 爆 i n t 的 情 况 , 所 以 我 们 考 虑 是 否 存 在 E m a x , 使 得 机 器 人 必 然 跳 过 所 有 建 筑 。 但由于E_i是呈指数级增长的,而i∈[1,100000],必然会出现爆int的情况,\\所以我们考虑是否存在E_{max},使得机器人必然跳过所有建筑。 Eii[1,100000]intEmax,使

在 整 个 二 分 的 过 程 中 , 需 要 判 断 的 是 E i 是 否 大 于 等 于 0 , 若 E i < 0 就 不 满 足 题 意 . 在整个二分的过程中,需要判断的是E_i是否大于等于0,若E_i<0就不满足题意. Ei0Ei<0.

所 以 考 察 E i = 2 E i − 1 − H i = E i − 1 + E i − 1 − H i , 当 E i − 1 > = H i 时 , E i 将 持 续 递 增 下 去 , 此 时 , 只 要 E 0 , E 1 , E 2 , . . . , E i − 1 > 0 , 那 么 E i > = E i − 1 > 0 恒 成 立 。 所以考察E_i=2E_{i-1}-H_i=E_{i-1}+E_{i-1}-H_i,当E_{i-1}>=H_{i}时,\\E_i将持续递增下去,此时,只要E_0,E_1,E_2,...,E_{i-1}>0,那么E_i>=E_{i-1}>0恒成立。 Ei=2Ei1Hi=Ei1+Ei1HiEi1>=HiEiE0,E1,E2,...,Ei1>0Ei>=Ei1>0

因 此 , 当 E i > = 100000 时 即 可 判 定 可 以 跳 跃 所 有 建 筑 。 因此,当E_i>=100000时即可判定可以跳跃所有建筑。 Ei>=100000

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
const int maxn=1e5+5;
int N,h[maxn];
bool check(int E)
{
    for(int i=1;i<=N;i++)
    {
        E=2*E-h[i];    ///
        if(E<0) return false;
        if(E>=1e5) return true;
    }
    return true;
}

int main()
{
    cin>>N;
    for(int i=1;i<=N;i++)
        scanf("%d",&h[i]);

    int l=1,r=1e5;//
    while(l<r)
    {
        int mid=l+r>>1;
        if(check(mid)) r=mid;
        else l=mid+1;
    }

    cout<<l<<endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值