原题链接: 730. 机器人跳跃问题 - AcWing题库
思路:
本题的难点就在于对题意的分析:假设机器人在第 k 个建筑,且它现在的能量值是 E,下一步它将跳到第 k+1 个建筑。如果H(k+1)>E,那么机器人就失去H(k+1)-E的能量值,否则它将得到E-H(k+1)的能量值
刚看到这些信息可能无从下手,乍一看好像还像个模拟,但如果稍微对题目信息做一下变形,会惊奇的发现一件事:如果H(k+1)>E,E=E-(H(k+1)-E)=2E-H(k+1),如果H(k+1)<E,E=E+(E-H(k+1))=2E-H(k+1)
这两个完全一样,所以看似分情况讨论,实则就一种操作,无需分情况,从起点到终点机械的执行这个操作即可
经过上述分析,题目就被抽象成:找到一个最小的E,从起点到终点重复执行*2-H(k+1)这个操作,直到终点,期间不能为负数
很显然这是一个二分了,那么分析一下时间复杂度,二分时间复杂度O(logn),check函数每次执行需要遍历整个h数组,所以整体时间复杂度为O(nlogn),本题数据范围1e5,log100000≈16,1e6<1e8,所以时间复杂度ok
所以做法如下:
- 套用二分模板
- 确定check函数
- 处理一些check函数的细节
代码如下:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1e5+10;
int h[N];
int temp=0;
int n;
bool check(int x)
{
for(int i=0;i<n;i++)
{
int now=2*x-h[i];
if(now>=temp) return true;//比最大值还大就没必要继续遍历了
if(now<0) return false;
x=now;
}
return true;
}
int main()
{
cin>>n;
for(int i=0;i<n;i++) cin>>h[i];
for(int i=0;i<n;i++) temp=max(temp,h[i]);
int l=0,r=1e5+10;
while(l<r)
{
int mid=l+r>>1;
if(check(mid)) r=mid;
else
l=mid+1;
}
cout<<l;
return 0;
}
作者:机械之忍
链接:https://www.acwing.com/activity/content/code/content/1949877/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
本人刚开始写题解不久,很多地方还不成熟,如果各位有疑问之处,或者我写的哪里有错误,欢迎私信我或者在下方留言
我的QQ:2907065305