二分:机器人跳跃问题 头条2019笔试题

题目搬运自:[AcWing 今日头条2019笔试题](https://www.acwing.com/problem/content/732/)

题目描述

机器人正在玩一个古老的基于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

看到这种题,首先不要多想,要动笔推一下。
如果h > E,那么 E = E - (h - E) = 2E - h,
否则 E = E + E - h = 2E - h。

此外,还要注意一下在 check 中溢出的问题,我们知道h有最大值,而且能满足条件的 e 是会不断递增的,所以在函数中写一个特判,当e > 1e5 时,以后的h一定都会跨过去 。 比如e = 1e5+1,即便后边遇到的h都是1e5,e还剩下1e5+2···依次下去,不断递增。

AC代码如下:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
typedef long long LL;
using namespace std;
// 除了动脑还要多动笔 推公式 
const int MAXN = 1e5 + 10;
int n, h[MAXN];
bool check(LL e) {
	int flag = 1;
	for(int i = 1; i <= n; i++) {
		if(e > 100000)	return true;
		// 巧妙的地方
		// 因为满足条件的e是严格递增的 所以判断一下e是否大于maxh即可 
		e = 2 * e - h[i];
		if(e < 0) {
			return false;
		}
	}
	return flag;
}

int main() {
	cin >> n;
	for(int i = 1; i <= n; i++) {
		scanf("%d", &h[i]);
	}
	int l = 1, r = 1e5, mid;
	while(l < r) {
		mid = l + r >> 1;
		if(check(mid))	r = mid;
		else    l = mid + 1;
	}
	cout << l << endl; 
	return 0;
}

我记录的二分模板在此。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值