蘭頓螞蟻是經典細胞自動機問題,藍橋杯考察模擬能力、邊界條件、方向狀態機轉換。本文詳細拆解題目要求、狀態轉移規律、Java 參考代碼逐行註解、測試用例驗證,助你拿下模擬類必考分。
輸入: 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
輸入: 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) 最快。
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);
}
}
蘭頓螞蟻最終會進入「高速公路」週期(周期 104 步,位移 (2,2))。若 k 極大(>10^7),可:
(x, y, dir, gridHash) 狀態cycles = (k - step) / period,x += cycles * dx,y += cycles * dy藍橋杯測試數據通常不需要此優化,但理解週期特性體現算法深度。