二分-字节跳动笔试题- 机器人跳跃问题
题目:
机器人正在玩一个古老的基于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,输入N个建筑的高度Hi,i∈[1,N]。
机 器 人 站 在 起 始 位 置 0 处 具 有 能 量 E 0 , 有 N 个 建 筑 , 从 低 处 往 高 处 跳 需 要 消 耗 能 量 , 从 高 处 往 低 处 跳 能 量 会 增 加 , 要 求 能 够 跳 跃 N 个 建 筑 的 最 低 初 始 能 量 E 0 m i n 。 机器人站在起始位置0处具有能量E_0,有N个建筑,从低处往高处跳需要消耗能量,\\从高处往低处跳能量会增加,要求能够跳跃N个建筑的最低初始能量E_{0min}。 机器人站在起始位置0处具有能量E0,有N个建筑,从低处往高处跳需要消耗能量,从高处往低处跳能量会增加,要求能够跳跃N个建筑的最低初始能量E0min。
设 机 器 人 在 第 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}。 设机器人在第i个位置处的能量为Ei,由题意:当后一个建筑的高度Hi+1>Ei时,机器人将失去Hi−1−Ei的能量,那么Ei+1=Ei−(Hi+1−Ei)=2Ei−Hi+1。当后一个建筑的高度Hi+1<Ei时,机器人将得到Ei−Hi−1的能量,那么Ei+1=Ei+(Ei−Hi−1)=2Ei−Hi+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]。 于是得到Ei的递推式Ei=2Ei−1−Hi,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}时不满足题意,\\答案满足二段性(单调性),所以考虑二分得到答案。 显然,Ei越大,就越可能满足题意,当Ei>=Emin时满足题意,当Ei<Emin时不满足题意,答案满足二段性(单调性),所以考虑二分得到答案。
但 由 于 E i 是 呈 指 数 级 增 长 的 , 而 i ∈ [ 1 , 100000 ] , 必 然 会 出 现 爆 i n t 的 情 况 , 所 以 我 们 考 虑 是 否 存 在 E m a x , 使 得 机 器 人 必 然 跳 过 所 有 建 筑 。 但由于E_i是呈指数级增长的,而i∈[1,100000],必然会出现爆int的情况,\\所以我们考虑是否存在E_{max},使得机器人必然跳过所有建筑。 但由于Ei是呈指数级增长的,而i∈[1,100000],必然会出现爆int的情况,所以我们考虑是否存在Emax,使得机器人必然跳过所有建筑。
在 整 个 二 分 的 过 程 中 , 需 要 判 断 的 是 E i 是 否 大 于 等 于 0 , 若 E i < 0 就 不 满 足 题 意 . 在整个二分的过程中,需要判断的是E_i是否大于等于0,若E_i<0就不满足题意. 在整个二分的过程中,需要判断的是Ei是否大于等于0,若Ei<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=2Ei−1−Hi=Ei−1+Ei−1−Hi,当Ei−1>=Hi时,Ei将持续递增下去,此时,只要E0,E1,E2,...,Ei−1>0,那么Ei>=Ei−1>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;
}