蓝桥杯二分算法通关指南:模板+真题+避坑,O(logn)秒杀大数据题
·
蓝桥杯二分算法通关指南:模板+真题+避坑,O(logn)秒杀大数据题
文章目录
在蓝桥杯算法竞赛中, 二分算法是性价比拉满的核心考点——模板固定、思路清晰、能轻松把暴力解法的O(n)、O(n²)复杂度优化到O(logn),完美解决大数据量超时问题。
二分的核心前提只有一个:解空间具有二段性(分界点一侧满足条件,另一侧不满足)。蓝桥杯不考复杂变形,只聚焦二分查找和二分答案两大高频题型,吃透这两类就能搞定90%的二分考题!
一、蓝桥杯二分核心题型(精简必背)
1. 二分查找(基础必考)
适用场景:有序数组中定位目标元素的边界,是填空题、简单编程题的常客。
常考2类核心边界:
- 左边界:数组中第一个满足条件的元素(如第一个≥目标值的下标)
- 右边界:数组中最后一个满足条件的元素(如最后一个≤目标值的下标)
延伸考点:区间计数(通过左右边界差值计算符合条件的元素个数)
2. 二分答案(进阶高频)
适用场景:解决**“最大值最小”“最小值最大”**类最优解问题(砍树、分巧克力、跳石头等蓝桥杯经典真题全是这个套路)。
核心三步法:
- 确定答案的取值范围
- 二分枚举中间值,判断该值是否满足题意(可行性判断)
- 根据可行性调整区间,最终找到最优解
二、Java真题实战(吃透两道题,覆盖所有考点)
例题1:二分查找——烦恼的高考志愿(蓝桥杯同类真题)
题目描述
m所学校有固定分数线,n位学生有各自估分。为每位学生选择分数线差值最小的学校,求所有学生的总差值和的最小值。
核心思路
- 先对学校分数线排序(二分的必备前提);
- 对每个学生的估分,用二分找第一个≥估分的学校分数线左边界;
- 比较边界位置和前一个位置的分数线差值,取最小值累加。
Java代码(核心标注)
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int m = sc.nextInt(); // 学校数量
int n = sc.nextInt(); // 学生数量
int[] schoolScore = new int[m];
for (int i = 0; i < m; i++) {
schoolScore[i] = sc.nextInt();
}
Arrays.sort(schoolScore); // 【核心1】排序,二分必须有序
long totalDiff = 0; // 【避坑】用long避免数据溢出
for (int i = 0; i < n; i++) {
int studentScore = sc.nextInt();
// 【核心2】二分查找左边界:第一个≥学生估分的位置
int left = 0, right = m - 1;
int pos = m; // 默认所有学校分数都小于学生估分
while (left <= right) {
int mid = left + (right - left) / 2; // 避免mid溢出
if (schoolScore[mid] >= studentScore) {
pos = mid; // 记录满足条件的位置
right = mid - 1; // 向左找更左的边界
} else {
left = mid + 1;
}
}
// 【边界处理】计算最小差值
int minDiff = Integer.MAX_VALUE;
if (pos < m) minDiff = Math.abs(schoolScore[pos] - studentScore);
if (pos > 0) minDiff = Math.min(minDiff, Math.abs(schoolScore[pos-1] - studentScore));
totalDiff += minDiff;
}
System.out.println(totalDiff);
}
}
考点总结
左边界查找、数组边界处理、排序+二分优化,彻底避免O(n*m)暴力超时。
例题2:二分答案——砍树(蓝桥杯高频真题)
题目描述
n棵树有不同高度,伐木机设置高度H,只能砍去高于H的部分。要求获取至少m长度的木材,求能满足条件的最大伐木高度H。
核心思路
- 确定H的范围:0 ~ 最高树的高度;
- 二分枚举mid高度,判断该高度能否砍出≥m的木材(可行性判断);
- 可行则尝试更大高度,不可行则减小高度,最终找到最大H。
Java代码(核心标注)
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
long n = sc.nextLong(); // 树的数量
long m = sc.nextLong(); // 需要的木材总长度
long[] treeHeight = new long[(int) n];
long maxH = 0; // 二分右边界:最高树的高度
for (int i = 0; i < n; i++) {
treeHeight[i] = sc.nextLong();
maxH = Math.max(maxH, treeHeight[i]);
}
// 【核心】二分答案模板
long left = 0, right = maxH;
while (left < right) {
// 【重点】mid=(left+right+1)/2,避免死循环
long mid = left + (right - left + 1) / 2;
long totalWood = 0; // 当前高度能获取的木材
// 可行性判断
for (long h : treeHeight) {
if (h > mid) totalWood += h - mid;
}
if (totalWood >= m) {
left = mid; // 可行,尝试更大高度
} else {
right = mid - 1; // 不可行,降低高度
}
}
System.out.println(left); // 最终left=right,就是最优解
}
}
考点总结
二分答案模板、可行性判断、mid计算避坑、long类型防溢出。
三、蓝桥杯二分必背应用场景
- 基础场景:有序数组边界查找、区间计数(填空题送分点);
- 进阶场景:最值类问题(砍树、分巧克力、跳石头等经典真题);
- 核心场景:暴力算法优化(解决大数据量超时的杀手锏)。
四、蓝桥杯二分备赛黄金法则(必记)
- 背熟两套模板:左边界查找、二分答案,考场直接套用,无需临时推导;
- 必用long类型:蓝桥杯大数据量极多,int极易溢出,直接用long更稳妥;
- 死守边界:mid计算、数组越界、循环条件是丢分重灾区,严格按模板写;
- 先排序再二分:二分的前提是有序,忘记排序直接0分。
二分算法是蓝桥杯的送分题,只要吃透模板、注意边界,考场就能快速AC。把这两道真题练熟,二分考点直接通关!
总结
- 二分核心是二段性解空间,蓝桥杯只考二分查找+二分答案两类;
- 两套固定模板直接背,考场不用推导,节省时间;
- 大数据量必用
long,牢记先排序、再二分,做好边界处理; - O(logn)复杂度完美解决超时问题,是竞赛性价比最高的算法之一。
更多推荐
所有评论(0)