diff --git a/solution/3500-3599/3568.Minimum Moves to Clean the Classroom/README.md b/solution/3500-3599/3568.Minimum Moves to Clean the Classroom/README.md index d90b1fbf9426b..8a975261a2c16 100644 --- a/solution/3500-3599/3568.Minimum Moves to Clean the Classroom/README.md +++ b/solution/3500-3599/3568.Minimum Moves to Clean the Classroom/README.md @@ -108,32 +108,275 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3500-3599/3568.Mi -### 方法一 +### 方法一:BFS + +我们可以使用广度优先搜索(BFS)来解决这个问题。首先,我们需要找到学生的起始位置,并记录所有垃圾的位置。然后,我们可以使用 BFS 来探索从起始位置出发的所有可能路径,同时跟踪当前能量和已收集的垃圾。 + +在 BFS 中,我们需要维护一个状态,包括当前的位置、剩余的能量和已收集的垃圾掩码。我们可以使用一个队列来存储这些状态,并使用一个集合来记录已经访问过的状态,以避免重复访问。 + +我们从起始位置开始,尝试向四个方向移动。如果移动到一个垃圾单元格,我们将更新已收集的垃圾掩码。如果移动到一个重置区域,我们将能量恢复到最大值。每次移动都会消耗 1 单位能量。 + +如果我们在 BFS 中找到了一个状态,其中已收集的垃圾掩码为 0(表示所有垃圾都已收集),则返回当前的移动次数。如果 BFS 完成后仍未找到这样的状态,则返回 -1。 + +时间复杂度 $O(m \times n \times \textit{energy} \times 2^{\textit{count}})$,空间复杂度 $O(m \times n \times \textit{energy} \times 2^{\textit{count}})$,其中 $m$ 和 $n$ 分别是网格的行数和列数,而 $\textit{count}$ 是垃圾单元格的数量。 #### Python3 ```python - +class Solution: + def minMoves(self, classroom: List[str], energy: int) -> int: + m, n = len(classroom), len(classroom[0]) + d = [[0] * n for _ in range(m)] + x = y = cnt = 0 + for i, row in enumerate(classroom): + for j, c in enumerate(row): + if c == "S": + x, y = i, j + elif c == "L": + d[i][j] = cnt + cnt += 1 + if cnt == 0: + return 0 + vis = [ + [[[False] * (1 << cnt) for _ in range(energy + 1)] for _ in range(n)] + for _ in range(m) + ] + q = [(x, y, energy, (1 << cnt) - 1)] + vis[x][y][energy][(1 << cnt) - 1] = True + dirs = (-1, 0, 1, 0, -1) + ans = 0 + while q: + t = q + q = [] + for i, j, cur_energy, mask in t: + if mask == 0: + return ans + if cur_energy <= 0: + continue + for k in range(4): + x, y = i + dirs[k], j + dirs[k + 1] + if 0 <= x < m and 0 <= y < n and classroom[x][y] != "X": + nxt_energy = ( + energy if classroom[x][y] == "R" else cur_energy - 1 + ) + nxt_mask = mask + if classroom[x][y] == "L": + nxt_mask &= ~(1 << d[x][y]) + if not vis[x][y][nxt_energy][nxt_mask]: + vis[x][y][nxt_energy][nxt_mask] = True + q.append((x, y, nxt_energy, nxt_mask)) + ans += 1 + return -1 ``` #### Java ```java - +class Solution { + public int minMoves(String[] classroom, int energy) { + int m = classroom.length, n = classroom[0].length(); + int[][] d = new int[m][n]; + int x = 0, y = 0, cnt = 0; + for (int i = 0; i < m; i++) { + String row = classroom[i]; + for (int j = 0; j < n; j++) { + char c = row.charAt(j); + if (c == 'S') { + x = i; + y = j; + } else if (c == 'L') { + d[i][j] = cnt; + cnt++; + } + } + } + if (cnt == 0) { + return 0; + } + boolean[][][][] vis = new boolean[m][n][energy + 1][1 << cnt]; + List q = new ArrayList<>(); + q.add(new int[] {x, y, energy, (1 << cnt) - 1}); + vis[x][y][energy][(1 << cnt) - 1] = true; + int[] dirs = {-1, 0, 1, 0, -1}; + int ans = 0; + while (!q.isEmpty()) { + List t = q; + q = new ArrayList<>(); + for (int[] state : t) { + int i = state[0], j = state[1], curEnergy = state[2], mask = state[3]; + if (mask == 0) { + return ans; + } + if (curEnergy <= 0) { + continue; + } + for (int k = 0; k < 4; k++) { + int nx = i + dirs[k], ny = j + dirs[k + 1]; + if (nx >= 0 && nx < m && ny >= 0 && ny < n && classroom[nx].charAt(ny) != 'X') { + int nxtEnergy = classroom[nx].charAt(ny) == 'R' ? energy : curEnergy - 1; + int nxtMask = mask; + if (classroom[nx].charAt(ny) == 'L') { + nxtMask &= ~(1 << d[nx][ny]); + } + if (!vis[nx][ny][nxtEnergy][nxtMask]) { + vis[nx][ny][nxtEnergy][nxtMask] = true; + q.add(new int[] {nx, ny, nxtEnergy, nxtMask}); + } + } + } + } + ans++; + } + return -1; + } +} ``` #### C++ ```cpp - +class Solution { +public: + int minMoves(vector& classroom, int energy) { + int m = classroom.size(), n = classroom[0].size(); + vector> d(m, vector(n, 0)); + int x = 0, y = 0, cnt = 0; + for (int i = 0; i < m; ++i) { + string& row = classroom[i]; + for (int j = 0; j < n; ++j) { + char c = row[j]; + if (c == 'S') { + x = i; + y = j; + } else if (c == 'L') { + d[i][j] = cnt; + cnt++; + } + } + } + if (cnt == 0) { + return 0; + } + vector>>> vis(m, vector>>(n, vector>(energy + 1, vector(1 << cnt, false)))); + queue> q; + q.emplace(x, y, energy, (1 << cnt) - 1); + vis[x][y][energy][(1 << cnt) - 1] = true; + vector dirs = {-1, 0, 1, 0, -1}; + int ans = 0; + while (!q.empty()) { + int sz = q.size(); + while (sz--) { + auto [i, j, cur_energy, mask] = q.front(); + q.pop(); + if (mask == 0) { + return ans; + } + if (cur_energy <= 0) { + continue; + } + for (int k = 0; k < 4; ++k) { + int nx = i + dirs[k], ny = j + dirs[k + 1]; + if (nx >= 0 && nx < m && ny >= 0 && ny < n && classroom[nx][ny] != 'X') { + int nxt_energy = classroom[nx][ny] == 'R' ? energy : cur_energy - 1; + int nxt_mask = mask; + if (classroom[nx][ny] == 'L') { + nxt_mask &= ~(1 << d[nx][ny]); + } + if (!vis[nx][ny][nxt_energy][nxt_mask]) { + vis[nx][ny][nxt_energy][nxt_mask] = true; + q.emplace(nx, ny, nxt_energy, nxt_mask); + } + } + } + } + ans++; + } + return -1; + } +}; ``` #### Go ```go - +func minMoves(classroom []string, energy int) int { + m, n := len(classroom), len(classroom[0]) + d := make([][]int, m) + for i := range d { + d[i] = make([]int, n) + } + x, y, cnt := 0, 0, 0 + for i := 0; i < m; i++ { + row := classroom[i] + for j := 0; j < n; j++ { + c := row[j] + if c == 'S' { + x, y = i, j + } else if c == 'L' { + d[i][j] = cnt + cnt++ + } + } + } + if cnt == 0 { + return 0 + } + + vis := make([][][][]bool, m) + for i := range vis { + vis[i] = make([][][]bool, n) + for j := range vis[i] { + vis[i][j] = make([][]bool, energy+1) + for e := range vis[i][j] { + vis[i][j][e] = make([]bool, 1< 0 { + t := q + q = []state{} + for _, s := range t { + i, j, curEnergy, mask := s.i, s.j, s.curEnergy, s.mask + if mask == 0 { + return ans + } + if curEnergy <= 0 { + continue + } + for k := 0; k < 4; k++ { + nx, ny := i+dirs[k], j+dirs[k+1] + if nx >= 0 && nx < m && ny >= 0 && ny < n && classroom[nx][ny] != 'X' { + var nxtEnergy int + if classroom[nx][ny] == 'R' { + nxtEnergy = energy + } else { + nxtEnergy = curEnergy - 1 + } + nxtMask := mask + if classroom[nx][ny] == 'L' { + nxtMask &= ^(1 << d[nx][ny]) + } + if !vis[nx][ny][nxtEnergy][nxtMask] { + vis[nx][ny][nxtEnergy][nxtMask] = true + q = append(q, state{nx, ny, nxtEnergy, nxtMask}) + } + } + } + } + ans++ + } + return -1 +} ``` diff --git a/solution/3500-3599/3568.Minimum Moves to Clean the Classroom/README_EN.md b/solution/3500-3599/3568.Minimum Moves to Clean the Classroom/README_EN.md index 1487920a2e632..b3782fc68e0b5 100644 --- a/solution/3500-3599/3568.Minimum Moves to Clean the Classroom/README_EN.md +++ b/solution/3500-3599/3568.Minimum Moves to Clean the Classroom/README_EN.md @@ -105,32 +105,275 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3500-3599/3568.Mi -### Solution 1 +### Solution 1: BFS + +We can use Breadth-First Search (BFS) to solve this problem. First, we need to find the student's starting position and record the locations of all garbage. Then, we can use BFS to explore all possible paths starting from the initial position, while tracking the current energy and the collected garbage. + +In BFS, we need to maintain a state that includes the current position, remaining energy, and a bitmask representing the collected garbage. We can use a queue to store these states and a set to record visited states to avoid revisiting them. + +We start from the initial position and try to move in four directions. If we move to a garbage cell, we update the collected garbage bitmask. If we move to a reset area, we restore the energy to its maximum value. Each move consumes 1 unit of energy. + +If we find a state in BFS where the garbage bitmask is 0 (meaning all garbage has been collected), we return the current number of moves. If BFS completes without finding such a state, we return -1. + +The time complexity is $O(m \times n \times \textit{energy} \times 2^{\textit{count}})$, and the space complexity is $O(m \times n \times \textit{energy} \times 2^{\textit{count}})$, where $m$ and $n$ are the number of rows and columns in the grid, and $\textit{count}$ is the number of garbage cells. #### Python3 ```python - +class Solution: + def minMoves(self, classroom: List[str], energy: int) -> int: + m, n = len(classroom), len(classroom[0]) + d = [[0] * n for _ in range(m)] + x = y = cnt = 0 + for i, row in enumerate(classroom): + for j, c in enumerate(row): + if c == "S": + x, y = i, j + elif c == "L": + d[i][j] = cnt + cnt += 1 + if cnt == 0: + return 0 + vis = [ + [[[False] * (1 << cnt) for _ in range(energy + 1)] for _ in range(n)] + for _ in range(m) + ] + q = [(x, y, energy, (1 << cnt) - 1)] + vis[x][y][energy][(1 << cnt) - 1] = True + dirs = (-1, 0, 1, 0, -1) + ans = 0 + while q: + t = q + q = [] + for i, j, cur_energy, mask in t: + if mask == 0: + return ans + if cur_energy <= 0: + continue + for k in range(4): + x, y = i + dirs[k], j + dirs[k + 1] + if 0 <= x < m and 0 <= y < n and classroom[x][y] != "X": + nxt_energy = ( + energy if classroom[x][y] == "R" else cur_energy - 1 + ) + nxt_mask = mask + if classroom[x][y] == "L": + nxt_mask &= ~(1 << d[x][y]) + if not vis[x][y][nxt_energy][nxt_mask]: + vis[x][y][nxt_energy][nxt_mask] = True + q.append((x, y, nxt_energy, nxt_mask)) + ans += 1 + return -1 ``` #### Java ```java - +class Solution { + public int minMoves(String[] classroom, int energy) { + int m = classroom.length, n = classroom[0].length(); + int[][] d = new int[m][n]; + int x = 0, y = 0, cnt = 0; + for (int i = 0; i < m; i++) { + String row = classroom[i]; + for (int j = 0; j < n; j++) { + char c = row.charAt(j); + if (c == 'S') { + x = i; + y = j; + } else if (c == 'L') { + d[i][j] = cnt; + cnt++; + } + } + } + if (cnt == 0) { + return 0; + } + boolean[][][][] vis = new boolean[m][n][energy + 1][1 << cnt]; + List q = new ArrayList<>(); + q.add(new int[] {x, y, energy, (1 << cnt) - 1}); + vis[x][y][energy][(1 << cnt) - 1] = true; + int[] dirs = {-1, 0, 1, 0, -1}; + int ans = 0; + while (!q.isEmpty()) { + List t = q; + q = new ArrayList<>(); + for (int[] state : t) { + int i = state[0], j = state[1], curEnergy = state[2], mask = state[3]; + if (mask == 0) { + return ans; + } + if (curEnergy <= 0) { + continue; + } + for (int k = 0; k < 4; k++) { + int nx = i + dirs[k], ny = j + dirs[k + 1]; + if (nx >= 0 && nx < m && ny >= 0 && ny < n && classroom[nx].charAt(ny) != 'X') { + int nxtEnergy = classroom[nx].charAt(ny) == 'R' ? energy : curEnergy - 1; + int nxtMask = mask; + if (classroom[nx].charAt(ny) == 'L') { + nxtMask &= ~(1 << d[nx][ny]); + } + if (!vis[nx][ny][nxtEnergy][nxtMask]) { + vis[nx][ny][nxtEnergy][nxtMask] = true; + q.add(new int[] {nx, ny, nxtEnergy, nxtMask}); + } + } + } + } + ans++; + } + return -1; + } +} ``` #### C++ ```cpp - +class Solution { +public: + int minMoves(vector& classroom, int energy) { + int m = classroom.size(), n = classroom[0].size(); + vector> d(m, vector(n, 0)); + int x = 0, y = 0, cnt = 0; + for (int i = 0; i < m; ++i) { + string& row = classroom[i]; + for (int j = 0; j < n; ++j) { + char c = row[j]; + if (c == 'S') { + x = i; + y = j; + } else if (c == 'L') { + d[i][j] = cnt; + cnt++; + } + } + } + if (cnt == 0) { + return 0; + } + vector>>> vis(m, vector>>(n, vector>(energy + 1, vector(1 << cnt, false)))); + queue> q; + q.emplace(x, y, energy, (1 << cnt) - 1); + vis[x][y][energy][(1 << cnt) - 1] = true; + vector dirs = {-1, 0, 1, 0, -1}; + int ans = 0; + while (!q.empty()) { + int sz = q.size(); + while (sz--) { + auto [i, j, cur_energy, mask] = q.front(); + q.pop(); + if (mask == 0) { + return ans; + } + if (cur_energy <= 0) { + continue; + } + for (int k = 0; k < 4; ++k) { + int nx = i + dirs[k], ny = j + dirs[k + 1]; + if (nx >= 0 && nx < m && ny >= 0 && ny < n && classroom[nx][ny] != 'X') { + int nxt_energy = classroom[nx][ny] == 'R' ? energy : cur_energy - 1; + int nxt_mask = mask; + if (classroom[nx][ny] == 'L') { + nxt_mask &= ~(1 << d[nx][ny]); + } + if (!vis[nx][ny][nxt_energy][nxt_mask]) { + vis[nx][ny][nxt_energy][nxt_mask] = true; + q.emplace(nx, ny, nxt_energy, nxt_mask); + } + } + } + } + ans++; + } + return -1; + } +}; ``` #### Go ```go - +func minMoves(classroom []string, energy int) int { + m, n := len(classroom), len(classroom[0]) + d := make([][]int, m) + for i := range d { + d[i] = make([]int, n) + } + x, y, cnt := 0, 0, 0 + for i := 0; i < m; i++ { + row := classroom[i] + for j := 0; j < n; j++ { + c := row[j] + if c == 'S' { + x, y = i, j + } else if c == 'L' { + d[i][j] = cnt + cnt++ + } + } + } + if cnt == 0 { + return 0 + } + + vis := make([][][][]bool, m) + for i := range vis { + vis[i] = make([][][]bool, n) + for j := range vis[i] { + vis[i][j] = make([][]bool, energy+1) + for e := range vis[i][j] { + vis[i][j][e] = make([]bool, 1< 0 { + t := q + q = []state{} + for _, s := range t { + i, j, curEnergy, mask := s.i, s.j, s.curEnergy, s.mask + if mask == 0 { + return ans + } + if curEnergy <= 0 { + continue + } + for k := 0; k < 4; k++ { + nx, ny := i+dirs[k], j+dirs[k+1] + if nx >= 0 && nx < m && ny >= 0 && ny < n && classroom[nx][ny] != 'X' { + var nxtEnergy int + if classroom[nx][ny] == 'R' { + nxtEnergy = energy + } else { + nxtEnergy = curEnergy - 1 + } + nxtMask := mask + if classroom[nx][ny] == 'L' { + nxtMask &= ^(1 << d[nx][ny]) + } + if !vis[nx][ny][nxtEnergy][nxtMask] { + vis[nx][ny][nxtEnergy][nxtMask] = true + q = append(q, state{nx, ny, nxtEnergy, nxtMask}) + } + } + } + } + ans++ + } + return -1 +} ``` diff --git a/solution/3500-3599/3568.Minimum Moves to Clean the Classroom/Solution.cpp b/solution/3500-3599/3568.Minimum Moves to Clean the Classroom/Solution.cpp new file mode 100644 index 0000000000000..c04b1128e4e95 --- /dev/null +++ b/solution/3500-3599/3568.Minimum Moves to Clean the Classroom/Solution.cpp @@ -0,0 +1,59 @@ +class Solution { +public: + int minMoves(vector& classroom, int energy) { + int m = classroom.size(), n = classroom[0].size(); + vector> d(m, vector(n, 0)); + int x = 0, y = 0, cnt = 0; + for (int i = 0; i < m; ++i) { + string& row = classroom[i]; + for (int j = 0; j < n; ++j) { + char c = row[j]; + if (c == 'S') { + x = i; + y = j; + } else if (c == 'L') { + d[i][j] = cnt; + cnt++; + } + } + } + if (cnt == 0) { + return 0; + } + vector>>> vis(m, vector>>(n, vector>(energy + 1, vector(1 << cnt, false)))); + queue> q; + q.emplace(x, y, energy, (1 << cnt) - 1); + vis[x][y][energy][(1 << cnt) - 1] = true; + vector dirs = {-1, 0, 1, 0, -1}; + int ans = 0; + while (!q.empty()) { + int sz = q.size(); + while (sz--) { + auto [i, j, cur_energy, mask] = q.front(); + q.pop(); + if (mask == 0) { + return ans; + } + if (cur_energy <= 0) { + continue; + } + for (int k = 0; k < 4; ++k) { + int nx = i + dirs[k], ny = j + dirs[k + 1]; + if (nx >= 0 && nx < m && ny >= 0 && ny < n && classroom[nx][ny] != 'X') { + int nxt_energy = classroom[nx][ny] == 'R' ? energy : cur_energy - 1; + int nxt_mask = mask; + if (classroom[nx][ny] == 'L') { + nxt_mask &= ~(1 << d[nx][ny]); + } + if (!vis[nx][ny][nxt_energy][nxt_mask]) { + vis[nx][ny][nxt_energy][nxt_mask] = true; + q.emplace(nx, ny, nxt_energy, nxt_mask); + } + } + } + } + ans++; + } + return -1; + } +}; diff --git a/solution/3500-3599/3568.Minimum Moves to Clean the Classroom/Solution.go b/solution/3500-3599/3568.Minimum Moves to Clean the Classroom/Solution.go new file mode 100644 index 0000000000000..4eae80894fc16 --- /dev/null +++ b/solution/3500-3599/3568.Minimum Moves to Clean the Classroom/Solution.go @@ -0,0 +1,76 @@ +func minMoves(classroom []string, energy int) int { + m, n := len(classroom), len(classroom[0]) + d := make([][]int, m) + for i := range d { + d[i] = make([]int, n) + } + x, y, cnt := 0, 0, 0 + for i := 0; i < m; i++ { + row := classroom[i] + for j := 0; j < n; j++ { + c := row[j] + if c == 'S' { + x, y = i, j + } else if c == 'L' { + d[i][j] = cnt + cnt++ + } + } + } + if cnt == 0 { + return 0 + } + + vis := make([][][][]bool, m) + for i := range vis { + vis[i] = make([][][]bool, n) + for j := range vis[i] { + vis[i][j] = make([][]bool, energy+1) + for e := range vis[i][j] { + vis[i][j][e] = make([]bool, 1< 0 { + t := q + q = []state{} + for _, s := range t { + i, j, curEnergy, mask := s.i, s.j, s.curEnergy, s.mask + if mask == 0 { + return ans + } + if curEnergy <= 0 { + continue + } + for k := 0; k < 4; k++ { + nx, ny := i+dirs[k], j+dirs[k+1] + if nx >= 0 && nx < m && ny >= 0 && ny < n && classroom[nx][ny] != 'X' { + var nxtEnergy int + if classroom[nx][ny] == 'R' { + nxtEnergy = energy + } else { + nxtEnergy = curEnergy - 1 + } + nxtMask := mask + if classroom[nx][ny] == 'L' { + nxtMask &= ^(1 << d[nx][ny]) + } + if !vis[nx][ny][nxtEnergy][nxtMask] { + vis[nx][ny][nxtEnergy][nxtMask] = true + q = append(q, state{nx, ny, nxtEnergy, nxtMask}) + } + } + } + } + ans++ + } + return -1 +} diff --git a/solution/3500-3599/3568.Minimum Moves to Clean the Classroom/Solution.java b/solution/3500-3599/3568.Minimum Moves to Clean the Classroom/Solution.java new file mode 100644 index 0000000000000..ecbd4bce0b3cc --- /dev/null +++ b/solution/3500-3599/3568.Minimum Moves to Clean the Classroom/Solution.java @@ -0,0 +1,58 @@ +class Solution { + public int minMoves(String[] classroom, int energy) { + int m = classroom.length, n = classroom[0].length(); + int[][] d = new int[m][n]; + int x = 0, y = 0, cnt = 0; + for (int i = 0; i < m; i++) { + String row = classroom[i]; + for (int j = 0; j < n; j++) { + char c = row.charAt(j); + if (c == 'S') { + x = i; + y = j; + } else if (c == 'L') { + d[i][j] = cnt; + cnt++; + } + } + } + if (cnt == 0) { + return 0; + } + boolean[][][][] vis = new boolean[m][n][energy + 1][1 << cnt]; + List q = new ArrayList<>(); + q.add(new int[] {x, y, energy, (1 << cnt) - 1}); + vis[x][y][energy][(1 << cnt) - 1] = true; + int[] dirs = {-1, 0, 1, 0, -1}; + int ans = 0; + while (!q.isEmpty()) { + List t = q; + q = new ArrayList<>(); + for (int[] state : t) { + int i = state[0], j = state[1], curEnergy = state[2], mask = state[3]; + if (mask == 0) { + return ans; + } + if (curEnergy <= 0) { + continue; + } + for (int k = 0; k < 4; k++) { + int nx = i + dirs[k], ny = j + dirs[k + 1]; + if (nx >= 0 && nx < m && ny >= 0 && ny < n && classroom[nx].charAt(ny) != 'X') { + int nxtEnergy = classroom[nx].charAt(ny) == 'R' ? energy : curEnergy - 1; + int nxtMask = mask; + if (classroom[nx].charAt(ny) == 'L') { + nxtMask &= ~(1 << d[nx][ny]); + } + if (!vis[nx][ny][nxtEnergy][nxtMask]) { + vis[nx][ny][nxtEnergy][nxtMask] = true; + q.add(new int[] {nx, ny, nxtEnergy, nxtMask}); + } + } + } + } + ans++; + } + return -1; + } +} diff --git a/solution/3500-3599/3568.Minimum Moves to Clean the Classroom/Solution.py b/solution/3500-3599/3568.Minimum Moves to Clean the Classroom/Solution.py new file mode 100644 index 0000000000000..6905f99eb1bd2 --- /dev/null +++ b/solution/3500-3599/3568.Minimum Moves to Clean the Classroom/Solution.py @@ -0,0 +1,44 @@ +class Solution: + def minMoves(self, classroom: List[str], energy: int) -> int: + m, n = len(classroom), len(classroom[0]) + d = [[0] * n for _ in range(m)] + x = y = cnt = 0 + for i, row in enumerate(classroom): + for j, c in enumerate(row): + if c == "S": + x, y = i, j + elif c == "L": + d[i][j] = cnt + cnt += 1 + if cnt == 0: + return 0 + vis = [ + [[[False] * (1 << cnt) for _ in range(energy + 1)] for _ in range(n)] + for _ in range(m) + ] + q = [(x, y, energy, (1 << cnt) - 1)] + vis[x][y][energy][(1 << cnt) - 1] = True + dirs = (-1, 0, 1, 0, -1) + ans = 0 + while q: + t = q + q = [] + for i, j, cur_energy, mask in t: + if mask == 0: + return ans + if cur_energy <= 0: + continue + for k in range(4): + x, y = i + dirs[k], j + dirs[k + 1] + if 0 <= x < m and 0 <= y < n and classroom[x][y] != "X": + nxt_energy = ( + energy if classroom[x][y] == "R" else cur_energy - 1 + ) + nxt_mask = mask + if classroom[x][y] == "L": + nxt_mask &= ~(1 << d[x][y]) + if not vis[x][y][nxt_energy][nxt_mask]: + vis[x][y][nxt_energy][nxt_mask] = True + q.append((x, y, nxt_energy, nxt_mask)) + ans += 1 + return -1