文章目录
- [一. 力扣 [875. 爱吃香蕉的珂珂](https://leetcode.cn/problems/koko-eating-bananas/description/)](#一. 力扣 875. 爱吃香蕉的珂珂)
-
- [1. 题目解析](#1. 题目解析)
- [2. 算法原理](#2. 算法原理)
- [3. 代码](#3. 代码)
- [二. 洛谷 [P1873 [COCI 2011/2012 #5] EKO / 砍树](https://www.luogu.com.cn/problem/P1873)](#5] EKO / 砍树](https://www.luogu.com.cn/problem/P1873))
-
- [1. 题目解析](#1. 题目解析)
- [2. 算法原理](#2. 算法原理)
- [3. 代码](#3. 代码)
- [三. 力扣 [410. 分割数组的最大值](https://leetcode.cn/problems/split-array-largest-sum/description/)](#三. 力扣 410. 分割数组的最大值)
-
- [1. 题目解析](#1. 题目解析)
- [2. 算法原理](#2. 算法原理)
- [3. 代码](#3. 代码)
- [四. 牛客 [机器人跳跃问题](https://www.nowcoder.com/practice/7037a3d57bbd4336856b8e16a9cafd71)](#四. 牛客 机器人跳跃问题)
-
- [1. 题目解析](#1. 题目解析)
- [2. 算法原理](#2. 算法原理)
- [3. 代码](#3. 代码)
博主学习二分答案的视频是从b站上找的, 资源 -> 算法讲解051【必备】二分答案法与相关题目
一. 力扣 875. 爱吃香蕉的珂珂
1. 题目解析
猴子很懒, 当piles[i] 的香蕉 < speed速度时, 不会直接去吃下一个位置的香蕉, 而是等待1小时结束后再去吃, 如果刚好为speed的倍数, 则直接去吃下一个位置的香蕉
2. 算法原理
3. 代码
java
class Solution {
public int minEatingSpeed(int[] piles, int h) {
long l = 1;
long r = 0;
for(int x : piles) {
r = Math.max(x, r);
}
long ans = 0;
while (l <= r) {
long mid = l + (r - l) / 2;
if (check(piles, h,mid)) {
ans = mid;
r = mid - 1;
}else {
l = mid + 1;
}
}
return (int)ans;
}
boolean check(int[] piles, int h, long mid) {
long time = 0;
for (int x : piles) {
time += (x + mid - 1) / mid;
}
return time <= h;
}
}
二. 洛谷 P1873 [COCI 2011/2012 #5] EKO / 砍树
1. 题目解析
2. 算法原理
3. 代码
java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
static int n;
static long m;
public static void main(String[] args) throws IOException {
long l = 0, r = 0;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
m = Long.parseLong(st.nextToken());
st = new StringTokenizer(br.readLine());
long[] tree = new long[n];
for (int i = 0; i < n; i++) {
tree[i] = Long.parseLong(st.nextToken());
}
for (long x : tree) {
r = Math.max(r, x);
}
long ans = 0;
while (l <= r) {
long mid = l + (r - l) / 2;
if (check(tree, mid, m)) {
ans = mid;
l = mid + 1;
}else {
r = mid - 1;
}
}
System.out.println(ans);
}
static boolean check(long[] tree, long mid, long m) {
long sum = 0;
for (long x : tree) {
if (x > mid) {
sum += (x - mid);
}
}
return sum >= m;
}
}
三. 力扣 410. 分割数组的最大值
1. 题目解析
题目意思还是很好理解的
2. 算法原理
正难则反 + 二分答案
3. 代码
java
class Solution {
int max = 0;
public int splitArray(int[] nums, int k) {
long l = 0, r = 0;
for (int x : nums) {
r += x;
max = Math.max(max, x);
}
long ans = 0;
l = max;
while (l <= r) {
long mid = l + (r - l) / 2;
if (check(nums, k, mid)) {
ans = mid;
r = mid - 1;
}else {
l = mid + 1;
}
}
return (int)ans;
}
boolean check(int[] nums, int k, long mid) {
int t = 0;
long sum = 0;
for (int x : nums) {
sum += x;
if (sum > mid) {
sum = x;
t++;
}
}
return t <= k - 1;
}
}
四. 牛客 机器人跳跃问题
1. 题目解析
能量大, 就加上差值, 能量小, 就减去差值
2. 算法原理
3. 代码
java
import java.util.*;
public class Main {
static int n;
static long max;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
n = in.nextInt();
long[] builds = new long[n];
long l = 0, r = 0;
for (int i = 0; i < n; i++) {
builds[i] = in.nextLong();
r = Math.max(r, builds[i]);
}
max = r;
long ans = 0;
while (l <= r) {
long mid = l + (r - l) / 2;
if (check(builds, mid)) {
ans = mid;
r = mid - 1;
}else {
l = mid + 1;
}
}
System.out.println(ans);
}
static boolean check(long[] builds, long mid) {
long sum = mid;
for (long x : builds) {
sum += (sum - x);
if (sum >= max) {
return true; // 当能量累积到max时, 后面就不用判断了, 必定通关
}
if (sum < 0) {
return false;
}
}
return true;
}
}







