首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

藍橋杯真題:蘭頓螞蟻模擬算法完整解析與 Java 實現

     編輯:Java 綜合教學

藍橋杯歷屆真題——蘭頓螞蟻:細胞自動機模擬、規則邏輯、邊界處理與 Java 代碼通關

蘭頓螞蟻是經典細胞自動機問題,藍橋杯考察模擬能力、邊界條件、方向狀態機轉換。本文詳細拆解題目要求、狀態轉移規律、Java 參考代碼逐行註解、測試用例驗證,助你拿下模擬類必考分。

一、題目還原

問題描述

  • m 行 n 列網格(3 < m,n < 100),0=白格,1=黑格
  • 螞蟻初始位置 (x,y)、朝向 s ∈ {U,D,L,R}、步數 k
  • 移動規則:
    • 黑格:右轉 90° → 格子翻白 → 前進一格
    • 白格:左轉 90° → 格子翻黑 → 前進一格
  • 輸出 k 步後螞蟻坐標 (p,q)

樣例 1

輸入:
5 6
0 0 0 0 0 0
0 0 0 0 0 0
0 0 1 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
2 3 L 5

輸出: 1 3

樣例 2

輸入:
3 3
0 0 0
1 1 1
1 1 1
1 1 U 6

輸出: 0 0

二、狀態機設計:方向轉換表

用兩個數組分別表示「左轉後方向」與「右轉後方向」,索引對應 {L, D, R, U} 循環:


// 索引順序:0=L, 1=D, 2=R, 3=U
char[] leftTurn  = {'D', 'R', 'U', 'L'};  // 當前方向 → 左轉後方向
char[] rightTurn = {'U', 'L', 'D', 'R'};  // 當前方向 → 右轉後方向

// 查找當前方向索引
int idx = -1;
for (int i = 0; i < 4; i++) if (dirs[i] == currentDir) { idx = i; break; }

// 左轉
currentDir = leftTurn[idx];
// 右轉
currentDir = rightTurn[idx];

也可用 Map 或 switch,數組 O(1) 最快。

三、完整 Java 參考代碼(含詳細註解)


import java.util.Scanner;

public class LangtonAnt {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        
        // 1. 讀網格尺寸
        int rows = in.nextInt();   // m
        int cols = in.nextInt();   // n
        
        // 2. 讀網格初始狀態
        int[][] grid = new int[rows][cols];
        for (int i = 0; i < rows; i++)
            for (int j = 0; j < cols; j++)
                grid[i][j] = in.nextInt();  // 0 白, 1 黑
        
        // 3. 讀螞蟻初始狀態
        int x = in.nextInt();      // 行
        int y = in.nextInt();      // 列
        char dir = in.next().charAt(0); // U/D/L/R
        int steps = in.nextInt();  // k
        
        // 4. 方向轉換表
        char[] leftTurn  = {'D', 'R', 'U', 'L'};  // L->D, D->R, R->U, U->L
        char[] rightTurn = {'U', 'L', 'D', 'R'};  // L->U, U->R, R->D, D->L
        char[] dirs = {'L', 'D', 'R', 'U'};       // 索引對應
        
        // 5. 模擬 k 步
        for (int step = 0; step < steps; step++) {
            // 找到當前方向索引
            int idx = 0;
            while (dirs[idx] != dir) idx++;
            
            if (grid[x][y] == 1) { // 黑格
                grid[x][y] = 0;    // 翻白
                dir = rightTurn[idx]; // 右轉
            } else {               // 白格
                grid[x][y] = 1;    // 翻黑
                dir = leftTurn[idx];  // 左轉
            }
            
            // 前進一格
            switch (dir) {
                case 'U': x--; break;
                case 'D': x++; break;
                case 'L': y--; break;
                case 'R': y++; break;
            }
            
            // 題目保證不會走出邊界,無需額外判斷
        }
        
        // 6. 輸出結果
        System.out.println(x + " " + y);
    }
}

四、關鍵點總結(易錯點)

  1. 方向數組順序必須一致:leftTurn/rightTurn/dirs 三個數組索引對應關係要對齊
  2. 先翻色、再轉向、再移動:順序不可亂
  3. 網格坐標系:x 為行(向下增),y 為列(向右增),U=x-1, D=x+1, L=y-1, R=y+1
  4. 題目隱含保證:螞蟻不會走出邊界,無需邊界檢查(但實際比賽建議加上防呆)
  5. 時間複雜度:O(k),k ≤ 10^9 時需找週期優化,但藍橋杯測試數據 k 較小,直接模擬即可

五、進階優化:大步數尋找週期(選做)

蘭頓螞蟻最終會進入「高速公路」週期(周期 104 步,位移 (2,2))。若 k 極大(>10^7),可:

  1. 模擬並記錄 (x, y, dir, gridHash) 狀態
  2. 檢測到重複狀態 → 計算週期長度、位移向量
  3. 快進:cycles = (k - step) / period,x += cycles * dx,y += cycles * dy
  4. 剩餘步數繼續模擬

藍橋杯測試數據通常不需要此優化,但理解週期特性體現算法深度。

六、總結

  • 蘭頓螞蟻 = 狀態機 + 網格翻轉 + 移動
  • 方向轉換用數組 O(1) 查表,避免冗長 switch
  • 嚴格遵循「翻色 → 轉向 → 移動」順序
  • 直接模擬通過藍橋杯測試數據,大步數可扩展週期檢測
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved