机器人正在玩一个古老的基于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\),
5
3 4 3 2 4
4
3
4 4 4
4
3
1 6 4
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;
}
原文:https://www.cnblogs.com/bangdexuanyuan/p/14418688.html