classSolution { public: intminPushBox(vector<vector<char>>& grid){ int m = grid.size(), n = grid[0].size(); int sx, sy, bx, by; // 玩家、箱子的初始位置 for (int x = 0; x < m; x++) { for (int y = 0; y < n; y++) { if (grid[x][y] == 'S') { sx = x; sy = y; } elseif (grid[x][y] == 'B') { bx = x; by = y; } } }
auto ok = [&](int x, int y) -> bool { // 不越界且不在墙上 return x >= 0 && x < m && y >= 0 && y < n && grid[x][y] != '#'; }; vector<int> d = {0, -1, 0, 1, 0};
vector<vector<int>> dp(m * n, vector<int>(m * n, INT_MAX)); queue<pair<int, int>> q; dp[sx * n + sy][bx * n + by] = 0; // 初始状态的推动次数为 0 q.push({sx * n + sy, bx * n + by}); while (!q.empty()) { queue<pair<int, int>> q1; while (!q.empty()) { auto [s1, b1] = q.front(); q.pop(); int sx1 = s1 / n, sy1 = s1 % n, bx1 = b1 / n, by1 = b1 % n; if (grid[bx1][by1] == 'T') { // 箱子已被推到目标处 return dp[s1][b1]; } for (int i = 0; i < 4; i++) { // 玩家向四个方向移动到另一个状态 int sx2 = sx1 + d[i], sy2 = sy1 + d[i + 1], s2 = sx2*n+sy2; if (!ok(sx2, sy2)) { // 玩家位置不合法 continue; } if (bx1 == sx2 && by1 == sy2) { // 推动箱子 int bx2 = bx1 + d[i], by2 = by1 + d[i + 1], b2 = bx2*n+by2; if (!ok(bx2, by2) || dp[s2][b2] <= dp[s1][b1] + 1) { // 箱子位置不合法 或 状态已访问 continue; } dp[s2][b2] = dp[s1][b1] + 1; q1.push({s2, b2}); } else { if (dp[s2][b1] <= dp[s1][b1]) { // 状态已访问 continue; } dp[s2][b1] = dp[s1][b1]; q.push({s2, b1}); } } } q.swap(q1); } return-1; } };
publicclassSolution { publicintMinPushBox(char[][] grid) { int m = grid.Length, n = grid[0].Length; int sx = -1, sy = -1, bx = -1, by = -1; // 玩家、箱子的初始位置 for (int x = 0; x < m; x++) { for (int y = 0; y < n; y++) { if (grid[x][y] == 'S') { sx = x; sy = y; } elseif (grid[x][y] == 'B') { bx = x; by = y; } } }
int[] d = {0, -1, 0, 1, 0};
int[][] dp = newint[m * n][]; for (int i = 0; i < m * n; i++) { dp[i] = newint[m * n]; Array.Fill(dp[i], int.MaxValue); } Queue<Tuple<int, int>> queue = new Queue<Tuple<int, int>>(); dp[sx * n + sy][bx * n + by] = 0; // 初始状态的推动次数为 0 queue.Enqueue(new Tuple<int, int>(sx * n + sy, bx * n + by)); while (queue.Count > 0) { Queue<Tuple<int, int>> queue1 = new Queue<Tuple<int, int>>(); while (queue.Count > 0) { Tuple<int, int> tuple = queue.Dequeue(); int s1 = tuple.Item1, b1 = tuple.Item2; int sx1 = s1 / n, sy1 = s1 % n, bx1 = b1 / n, by1 = b1 % n; if (grid[bx1][by1] == 'T') { // 箱子已被推到目标处 return dp[s1][b1]; } for (int i = 0; i < 4; i++) { // 玩家向四个方向移动到另一个状态 int sx2 = sx1 + d[i], sy2 = sy1 + d[i + 1], s2 = sx2*n+sy2; if (!Ok(grid, m, n, sx2, sy2)) { // 玩家位置不合法 continue; } if (bx1 == sx2 && by1 == sy2) { // 推动箱子 int bx2 = bx1 + d[i], by2 = by1 + d[i + 1], b2 = bx2*n+by2; if (!Ok(grid, m, n, bx2, by2) || dp[s2][b2] <= dp[s1][b1] + 1) { // 箱子位置不合法 或 状态已访问 continue; } dp[s2][b2] = dp[s1][b1] + 1; queue1.Enqueue(new Tuple<int, int>(s2, b2)); } else { if (dp[s2][b1] <= dp[s1][b1]) { // 状态已访问 continue; } dp[s2][b1] = dp[s1][b1]; queue.Enqueue(new Tuple<int, int>(s2, b1)); } } } queue = queue1; } return-1; }
publicboolOk(char[][] grid, int m, int n, int x, int y) { // 不越界且不在墙上 return x >= 0 && x < m && y >= 0 && y < n && grid[x][y] != '#'; } }
classSolution: defminPushBox(self, grid: List[List[str]]) -> int: m = len(grid) n = len(grid[0]) sx, sy, bx, by = None, None, None, None# 玩家、箱子的初始位置 for x inrange(m): for y inrange(n): if grid[x][y] == 'S': sx = x sy = y elif grid[x][y] == 'B': bx = x by = y
# 不越界且不在墙上 defok(x, y): return (0 <= x < m and0 <= y < n and grid[x][y] != '#')
d = [0, -1, 0, 1, 0]
dp = [[float('inf')] * (m * n) for _ inrange(m * n)] dp[sx * n + sy][bx * n + by] = 0# 初始状态的推动次数为 0 q = deque([(sx * n + sy, bx * n + by)]) while q: q1 = deque() while q: s1, b1 = q.popleft() sx1, sy1 = s1 // n, s1 % n bx1, by1 = b1 // n, b1 % n if grid[bx1][by1] == 'T': # 箱子已被推到目标处 return dp[s1][b1] for i inrange(4): # 玩家向四个方向移动到另一个状态 sx2, sy2 = sx1 + d[i], sy1 + d[i + 1] s2 = sx2 * n + sy2 ifnot ok(sx2, sy2): # 玩家位置不合法 continue if sx2 == bx1 and sy2 == by1: # 推动箱子 bx2, by2 = bx1 + d[i], by1 + d[i + 1] b2 = bx2 * n + by2 ifnot ok(bx2, by2) or dp[s2][b2] <= dp[s1][b1] + 1: # 箱子位置不合法 或 状态已访问 continue dp[s2][b2] = dp[s1][b1] + 1 q1.append((s2, b2)) else: if dp[s2][b1] <= dp[s1][b1]: # 状态已访问 continue dp[s2][b1] = dp[s1][b1] q.append((s2, b1)) q, q1 = q1, q return -1
funcminPushBox(grid [][]byte)int { m, n := len(grid), len(grid[0]) var sx, sy, bx, by int// 玩家、箱子的初始位置 for x := 0; x < m; x++ { for y := 0; y < n; y++ { if grid[x][y] == 'S' { sx, sy = x, y } elseif grid[x][y] == 'B' { bx, by = x, y } } }
ok := func(x, y int)bool { // 不越界且不在墙上 return x >= 0 && x < m && y >= 0 && y < n && grid[x][y] != '#' } d := []int{0, -1, 0, 1, 0}
var minPushBox = function(grid) { const m = grid.length, n = grid[0].length; let sx = -1, sy = -1, bx = -1, by = -1; // 玩家、箱子的初始位置 for (let x = 0; x < m; x++) { for (let y = 0; y < n; y++) { if (grid[x][y] === 'S') { sx = x; sy = y; } elseif (grid[x][y] === 'B') { bx = x; by = y; } } }