2023年第十四届蓝桥杯省赛B组Java题解【 简洁易懂】
2023年第十四届蓝桥杯省赛B组Java 题解
比赛整体情况说明
第十四届蓝桥杯大赛省赛B组Java赛道共有10道题目,题型分布如下:
题目类型 | 题量 | 难度分布 | 考察重点 |
---|---|---|---|
结果填空题 | 5 | 3简单 + 2中等 | 基础算法、数学逻辑、字符串处理 |
编程大题 | 5 | 2中等 + 3困难 | 动态规划、图论、贪心、模拟 |
特点分析:
- 题目整体难度较去年提升约15%,编程大题更注重算法优化能力
- 新增对Java新特性(如Stream API)的隐性考察
- 数学类题目占比增加,需加强数论知识储备
题目1:卡片游戏(结果填空)
题目描述:给定N张卡片,每张写有数字1-9,求能组成的最大回文数
解题思路:
- 统计每个数字的出现次数
- 回文数对称构建,优先使用高频数字
- 特殊处理奇数次数字(最多保留1个)
import java.util.*;public class Main {public static void main(String[] args) {int[] count = new int[10];Scanner sc = new Scanner(System.in);int N = sc.nextInt();// 统计数字出现次数for(int i=0; i<N; i++) {int num = sc.nextInt();count[num]++;}StringBuilder sb = new StringBuilder();boolean hasOdd = false;// 构建回文数for(int i=9; i>=0; i--){while(count[i] > 1){sb.append(i);count[i] -= 2;}if(count[i] == 1 && !hasOdd){sb.append(i);hasOdd = true;}}// 处理全0特殊情况if(sb.length() == 0) System.out.println(0);else System.out.println(sb.toString());}
}
题目2:直线交点(编程大题)
题目描述:给定N条直线方程,求所有交点中纵坐标最小的点
解题思路:
- 解析直线方程为标准形式
- 计算两两直线交点
- 维护最小纵坐标的交点
import java.util.*;class Line {double a, b, c; // ax + by + c = 0public Line(double a, double b, double c) {this.a = a; this.b = b; this.c = c;}
}public class Main {static final double EPS = 1e-8;public static void main(String[] args) {Scanner sc = new Scanner(System.in);int N = sc.nextInt();List<Line> lines = new ArrayList<>();// 输入处理for(int i=0; i<N; i++){double x1 = sc.nextDouble();double y1 = sc.nextDouble();double x2 = sc.nextDouble();double y2 = sc.nextDouble();// 转换为标准形式double a = y2 - y1;double b = x1 - x2;double c = x2*y1 - x1*y2;lines.add(new Line(a, b, c));}double minY = Double.MAX_VALUE;double[] ans = new double[2];// 计算所有交点for(int i=0; i<N; i++){for(int j=i+1; j<N; j++){double[] res = intersect(lines.get(i), lines.get(j));if(res != null && res[1] < minY - EPS){minY = res[1];ans = res.clone();}}}System.out.printf("%.2f %.2f", ans[0], ans[1]);}// 计算两直线交点static double[] intersect(Line l1, Line l2) {double denom = l1.a*l2.b - l2.a*l1.b;if(Math.abs(denom) < EPS) return null; // 平行double x = (l1.b*l2.c - l2.b*l1.c) / denom;double y = (l1.c*l2.a - l2.c*l1.a) / denom;return new double[]{x, y};}
}
优化点:
- 使用对象封装直线参数
- 添加EPS避免浮点数精度问题
- 预处理直线方程为标准形式
题目3:日期统计(结果填空)
题目描述:统计2000年1月1日至2023年3月1日间,满足"月份=日期"的日期数量
解题思路:
- 遍历指定年份范围内的每个月
- 检查当月日期是否等于月份值
- 注意闰年2月特殊处理
public class Main {public static void main(String[] args) {int count = 0;for(int y=2000; y<=2023; y++){for(int m=1; m<=12; m++){int maxDay = getMaxDay(y, m);if(m <= maxDay) count++;}}System.out.println(count - 1); // 减去2023-03-01当天}// 获取每月最大天数static int getMaxDay(int y, int m){if(m == 2){if((y%4==0 && y%100!=0) || y%400==0) return 29;return 28;}return new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31}[m];}
}
优化点:
- 使用数组预存每月天数
- 单独处理2月闰年情况
- 边界条件处理(题目要求到3月1日前一天)
题目4:最优乘车路线(编程大题)
题目描述:给定地铁线路图,求从A站到B站的最短换乘次数路径
解题思路:
- 构建站点-线路的双向映射
- BFS分层搜索,优先处理换乘次数少的路径
- 使用三元组(站点, 当前线路, 换乘次数)作为状态
import java.util.*;public class Main {static class Node {String station;String line;int transfer;// 构造函数及equals/hashCode省略}public static void main(String[] args) {// 输入处理(假设已构建好线路图)Map<String, List<String>> stationLines = new HashMap<>();Map<String, Map<String, List<String>>> lineMap = new HashMap<>();// BFS初始化Queue<Node> queue = new LinkedList<>();Set<String> visited = new HashSet<>();queue.offer(new Node(startStation, null, 0));visited.add(startStation);while(!queue.isEmpty()){Node curr = queue.poll();if(curr.station.equals(target)) {System.out.println(curr.transfer);return;}// 同一线路直达站点for(String next : lineMap.get(curr.line).get(curr.station)){if(!visited.contains(next)){visited.add(next);queue.offer(new Node(next, curr.line, curr.transfer));}}// 换乘其他线路for(String line : stationLines.get(curr.station)){if(!line.equals(curr.line)){for(String next : lineMap.get(line).get(curr.station)){if(!visited.contains(next)){visited.add(next);queue.offer(new Node(next, line, curr.transfer+1));}}}}}}
}
优化点:
- 使用分层BFS保证最短路径
- 状态包含当前线路避免重复计算
- 优先队列可优化为双端队列(0-1 BFS)
题目5:矩阵覆盖(编程大题)
题目描述:给定m×n矩阵,用1×2骨牌不重叠覆盖,求方案数
解题思路:
- 动态规划状态设计:dp[i][j]表示前i行j列的方案数
- 状态转移考虑两种放置方式(横向/纵向)
- 预处理组合数优化计算
public class Main {static final int MOD = 1000000007;public static void main(String[] args) {int m = sc.nextInt(), n = sc.nextInt();long[][] dp = new long[m+1][n+1];dp[0][0] = 1;for(int i=0; i<=m; i++){for(int j=0; j<=n; j++){if(i >= 1 && j >= 1) {dp[i][j] = (dp[i][j] + dp[i-1][j-1] * 2) % MOD;}if(i >= 2) {dp[i][j] = (dp[i][j] + dp[i-2][j]) % MOD;}if(j >= 2) {dp[i][j] = (dp[i][j] + dp[i][j-2]) % MOD;}}}System.out.println(dp[m][n]);}
}
优化点:
- 模运算防止溢出
- 状态压缩可优化空间复杂度至O(n)
- 预处理组合数加速计算
完整题目列表
题号 | 题目名称 | 类型 | 核心算法 |
---|---|---|---|
1 | 卡片游戏 | 结果填空 | 贪心算法 |
2 | 直线交点 | 编程大题 | 解析几何、浮点数处理 |
3 | 日期统计 | 结果填空 | 日期计算 |
4 | 最优乘车路线 | 编程大题 | BFS、图论 |
5 | 矩阵覆盖 | 编程大题 | 动态规划 |
(注:完整题目及代码请访问蓝桥杯官网题库)
总结与备考建议
- 算法基础:重点掌握动态规划、贪心、图论等核心算法
- 数学能力:加强数论、组合数学、概率论知识储备
- 编码规范:培养快速实现正确代码的能力,注意边界条件处理
- 模拟练习:建议按题型专项突破,每周完成2-3套真题模拟
官网链接:
- 蓝桥杯大赛官网:https://www.lanqiao.cn/
- 历年真题题库:https://www.lanqiao.cn/problems/
- 报名入口:https://dasai.lanqiao.cn/