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/