机器人跳跃问题_字节跳动2019春招研发部分编程题汇总_牛客网
参考:AcWing 机器人跳跃问题 二分 - haust_fx - 博客园
可以模拟第一个测试例子,初始能量值为4:
建筑编号:0 1 2 3 4 5
建筑高度:0 3 4 3 2 4
能量值: 4 5 6 9 16 28
所以能够保证全过程能力值不为负(最后的能量值不一定为0的噢)。
初始能量值为3:
建筑编号:0 1 2 3 4 5
建筑高度:0 3 4 3 2 4
能量值: 3 3 2 1 0 -4
出现负数,不合题意。
假设所有建筑物中的最大高度为max
的话,若在变化过程中,能量值E >= max
的话,则之后每一步的都有E >= 0
。
证明很简单:
若某一步的E >= max
,则下一步的能量值为 E + E - h[i] >= E + max - h[i]
。
又有max - h[i] >= 0
,所以下一步的能量值 E + E - h[i] = 2 * E - h[i] >= E >= 0
。
由于我们要寻找的是一个最小的临界值,也就是下界,这种情况一般会使用二分法:寻找第一个符合要求的值。而二分的区间,可以取为了保证尽量取到更多的数(0~一个很大的值),所以可以把这个很大的值设置的大一些,比如1000000这样,反正二分也很快。
#include <iostream>
using namespace std;
const int N = 1000000;
int n;
int h[N];
bool check(int e) { //判断能否使得初始能量为mid时,全过程能量非负
for (int i = 1; i <= n; i++) { //推一遍即可
e = e * 2 - h[i];
if (e >= 1e6) return true;//根据上面的性质判断,防止数值继续增大至溢出
if (e < 0) return false;//过程中出现负值
}
return true;
}
int main() {
cin >> n;
for (int i = 1; i <= n; i++) cin >> h[i];
int l = 0, r = 1e6;
while (l <= r) {//二分寻找满足要求的下界
int mid = l + r >> 1;
if (check(mid)){
if(mid == l || !check(mid-1)){
cout << mid << endl;
return 0;
}else r = mid - 1;
}
else l = mid + 1;
}
return 0;
}
另外看评论里有很多数学方法解的:机器人跳跃问题_字节跳动笔试题_牛客网
emm,我觉得笔试/面试的时候应该是想不出数学方法来的,不过数学方法确实很漂亮。