本题的思路是使用二分寻找能量x,然后判断机器人使用这个能量是否能通关,若能通关,返回true;若不通关,返回false;以此作为check函数,缩小答案范围。
本题要注意的点:
1.题目中的 “如果 H(k+1)>E,那么机器人就失去 H(k+1)−E 的能量值,否则它将得到 E−H(k+1) 的能量值” 表示为
if(num[i]>x) {
x-=num[i]-x;
}else {
x+=x-num[i];
}
可以进行优化
当 H(k+1)>E时,机器人的能量为x’=x-(H(k+1)-x) 等价于x’=2x-H(k+1)
当H(k+1)<E时,机器人的能量为 x’=x+(x-H(k+1)) 等价于x’=2x-H(k+1)
两个形式相同,因此我们可以不用判断,直接写就可以
- 本题中能量一直加下去会爆int,long也会爆,因此需要优化。当能量大于等于柱子的最大高度maxh的时候,由于跳到下一个柱子所需要的能量为2*x-H(k+1) 即 x+x-H(k+1) 又因为此时x>=maxh 而由于是最大高度,maxh>=H(k+1) 因此x-H(k+1)>=0 则x+x-H(k+1)>=x,也就是说当能量大于等于最大高度的时候,新能量是单调不减的,也就是一定大于0,此时一定是符合题意的。因此我们可以在能量大于等于最大高度的时候,就直接返回true。
错误写法
import java.util.*;
public class Main {
static int N=100010;
static int [] num=new int[N];
static int n;
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
n=sc.nextInt();
for(int i=1;i<=n;i++) {
num[i]=sc.nextInt();
}
int l=-1;
int r=100010;
// 多了肯定能过关
while(l+1<r) {
int mid=(l+r)/2;
if(check(mid)) {
r=mid;
}else {
l=mid;
}
}
if(check(l)) {
System.out.println(l);
}else {
System.out.println(r);
}
}
public static boolean check(int x) {
// 先上第一个
for(int i=1;i<=n;i++) {
if(num[i]>x) {
x-=num[i]-x;
}else {
x+=x-num[i];
}
if(x<0) {
return false;
}
}
return true;
}
}
此时会爆int 然后变成负数,返回false
正确写法
import java.util.*;
public class Main {
static int N=100010;
static int [] num=new int[N];
static int n;
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
n=sc.nextInt();
for(int i=1;i<=n;i++) {
num[i]=sc.nextInt();
}
int l=0;
// 当能量等于最大高度maxh的时候 跳到下一个柱子上的能量为 x=x*2-hi 由于x>maxh 而max>hi 因此x'=x+x-hi x-hi一定大于0 则x' 一定大于0
// 因此当能量大于等于最大高度maxh的时候 能量是单调递增的 一定大于0则 一定能过关
int r=(int)1e5;
// 多了肯定能过关
while(l+1<r) {
int mid=(l+r)/2;
if(check(mid)) {
r=mid;
}else {
l=mid;
}
}
if(check(l)) {
System.out.println(l);
}else {
System.out.println(r);
}
}
public static boolean check(int x) {
for(int i=1;i<=n;i++) {
x=2*x-num[i]; // 计算到达下一个柱子的能量
// 当能量大于等于最大高度的时候 此时能量一定是单调递增的 也就是说一定是大于等于0的 则可以提前结束 否则会爆int 和long
// 这里我们可以取柱子的最大值1e5
if(x>1e5) {
return true;
}
if(x<0) {
return false;
}
}
// 若在0~1e5之间 则说明也能通关 只要不小于0即可
return true;
}
}