机器人跳跃问题

题面

机器人跳跃问题

机器人正在玩一个古老的基于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)≤10^5\),

输入样例1:

5
3 4 3 2 4

输出样例1:

4

输入样例2:

3
4 4 4

输出样例2:

4

输入样例3:

3
1 6 4

输出样例3:

3

题解

这道题是一道实数域进行二分的题目

比整数二分要好写,不用考虑边界死循环的问题

只要我们限定住我们的精确度就好了,(一个while循环搞定)

那么只要大力二分就好了

下面主要来说说check函数的部分

精髓就在check函数,即判断当前二分的答案是否合法的函数

依据题意,其实就是每次都让你的E在原来的基础上先乘2再减去你下一个要跳去的楼高(拿笔推一下就好)

每次做完这样一轮运算后,检查当前的E是否为负数

如果为负数直接return false

否则一直进行,直到进行n轮后还没退出,那么我们就返回true

最后用ceil函数向上取整并输出r即可

代码

#include<bits/stdc++.h>
using namespace std;
double h[200000];
int n;

bool check(double mid)
{
    for(int i=1;i<=n;i++)
    {
        mid=mid*2-h[i];
        if(mid<0)
        {
            return false;
        }
    }
    return true;
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%lf",&h[i]);
    }
    double l=0;
    double r=1e8;
    while(r-l>0.00001)
    {
        double mid=(r+l)/2;
        if(check(mid))
        {
            r=mid;
        }
        else l=mid;
    }
    cout<<ceil(r)<<endl;
    return 0;
}

posted @ 2021-02-19 23:17  邦的轩辕  阅读(135)  评论(0编辑  收藏  举报