730. 机器人跳跃问题 Java 题解(二分)

730. 机器人跳跃问题 Java 题解(二分)_第1张图片 输入样例1:

5
3 4 3 2 4

输出样例1:

4

输入样例2:

3
4 4 4

输出样例2:

4

输入样例3:

3
1 6 4

输出样例3:

3

解题思路:

从题中得出能量的变化关系:即2*e-arr[i];而要求的是在正值的情况下的e的最小值,所以只要通过二分找出符合条件的值即可。

在遍历数组中的值时,由于每次都是在上一次的能量值翻倍后再减去数组的中的某一值,所以再翻倍时会爆出int的范围,甚至long也会爆,只能用java中的BigInteger类进行相乘。

优化:在相乘时,可以得出当某一时刻的能量值比数组中元素的最大值还要大时,那么后面再相乘时只会越来越大,更不可能出现负值。所以只要某一刻能量比数组中元素大时,可以直接认为后面元素都满足正值条件。

Java代码:(优化前)

import java.io.*;
import java.math.BigInteger;

public class Main {
	public static void main(String[] args) throws NumberFormatException, IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		int n = Integer.parseInt(br.readLine());
		int []arr = new int[n];
		String[] split = br.readLine().split(" ");
		for(int i = 0; i < n; i++) {
			arr[i] = Integer.parseInt(split[i]);
		}

		int l = 1;
		int r = 10000;
		while(l < r) {
			int mid = l + r >> 1;//二分
			boolean tag = true;
			BigInteger temp = new BigInteger(mid + "");
			int i = 0;
			for(i = 0; i < n; i++) {
				BigInteger num = temp.multiply(new BigInteger("2")).subtract(new BigInteger(arr[i] + ""));
				if(num.compareTo(new BigInteger("0")) < 0) {//出现负值时
					tag =false;//标记tag
					break;
				}else {
					temp = num;
				}
			}
			if(tag) r = mid;//说明数够大,没有出现负值,应该缩小,移动右端点
			else l = mid + 1;//说明数取的小了,应扩大,移动左端点
		}
		System.out.println(l);
	}
}

Java代码:(优化后)

import java.io.*;

public class Main {
	static int []arr;
	static int max;
	
	public static void main(String[] args) throws NumberFormatException, IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		int n = Integer.parseInt(br.readLine());
		arr = new int[n];
		String[] split = br.readLine().split(" ");
		max = arr[0];
		for(int i = 0; i < n; i++) {
			arr[i] = Integer.parseInt(split[i]);
			max = arr[i] > max ? arr[i] : max;//找出数组中的最大值
		}
		
		int l = 1, r = 100000;
		while(l < r) {
			int mid = l + r >> 1;
			if(check(mid)) r = mid;
			else l = mid + 1;
		}
		System.out.println(r);
	}
	
	public static boolean check(int e) {//优化检查函数
		for(int i = 0; i < arr.length; i++) {
			e = e * 2 - arr[i];
			if(e < 0)return false;
			if(e >= max) return true;//当某一刻能量比数组中能量的最大值还要大是,不管之后数组值如何,都不会变为负值
		}
		return true;
	}
}

你可能感兴趣的:(二分)