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

题目大概说了个什么意思呢,前面有不同高度的楼,机器人开始从当前位置跳跃,自身有一个能量值,每次跳跃的时候会进行判断

如果目前“能量>高度”
那么跳跃之后的能量值就变成了(能量 + (能量 - 高度))

如果目前“能量<高度”
那么跳跃之后的能量值就变成了(能量 - (高度 - 能量))

看起来跟楼层高度差好像没什么关系,不是平常的爬几层消耗几格能量,一开始还挺懵逼的,高中的时候数学老师告诉我,不管会不会,别光看,动笔算一算,看看自己到底是死在哪,于是设当前的能量是E推算一下

举个栗子
用测试数据3 4 3 2 4来举例,当前在第一个位置,能量是E,那么跳下一个位置以后的能量,有两种可能,一种是E < 4;一种是E > 4
但是最后的结果都是2E - 4;于是乎发现了每一次跳跃之后,能量都会变成2E - H

有了这个结论就好说了,数据范围给的是0 ~ 100000;我们用二分法来找到最合适的那个数据值,每次找到一个之后,就推算一遍看看这个能量值能不能跳到最后(跳到最后的条件就是能量值不会为负数)。代码如下:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>

using namespace std;

const int N = 100010;
int q[N];

//这个函数用来判断当前的能量值能不能跳到最后,最终返回值也是看正数还是负数
int get(long long e, int len)
{
    for(int i = 0 ; i < len ; i++)
    {
        if(e - q[i] > 100000)
            return 1;
        e = 2 * e - q[i];
        if(e < 0)
            return e;
    }
    return 1;
}

int main()
{
    int n;
    cin >> n;
    for(int i = 0 ; i < n ; i ++ )  scanf("%d", &q[i]);
    int l = 0, r = 100000;
    while(l < r)//二分查找能量值
    {
        long long mid = l + r >> 1;
        if(get(mid, n) > 0)    r = mid;
        else    l = mid + 1;
    }
    cout << l << endl;
    return 0;
}

注: 因为能量值最初也是会从50000开始,如果数据楼层比较低的地方,那么他不断的叠加能量,就会爆int,long long也会爆,就会出现能量太多导致负数的情况,所以在get函数中增加一个判断,如果当前的能量远大于楼层的高度,就直接return了
还有一点,因为最后我们要的是大于0的哪一个结果,所以判断条件用的是 ">0"