diff --git a/solution/3200-3299/3283.Maximum Number of Moves to Kill All Pawns/README.md b/solution/3200-3299/3283.Maximum Number of Moves to Kill All Pawns/README.md index 84d6b4ea988b6..f513534d4195c 100644 --- a/solution/3200-3299/3283.Maximum Number of Moves to Kill All Pawns/README.md +++ b/solution/3200-3299/3283.Maximum Number of Moves to Kill All Pawns/README.md @@ -99,32 +99,279 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3200-3299/3283.Ma -### 方法一 +### 方法一:BFS + 状态压缩 + 记忆化搜索 - +我们首先预处理出每个兵到棋盘上任意一个位置的马的最短距离,记录在数组 $\textit{dist}$ 中,即 $\textit{dist}[i][x][y]$ 表示第 $i$ 个兵到 $(x, y)$ 位置的马的最短距离。 + +接下来,我们设计一个函数 $\text{dfs}(\textit{last}, \textit{state}, \textit{k})$,其中 $\textit{last}$ 表示上一个吃掉的兵的编号,而 $\textit{state}$ 表示当前还剩下的兵的状态,而 $\textit{k}$ 表示当前是 Alice 还是 Bob 的回合。函数的返回值表示当前回合的最大移动次数。那么答案为 $\text{dfs}(n, 2^n-1, 1)$。这里我们初始时上一个吃掉的兵的编号记为 $n$,这也是马所在的位置。 + +函数 $\text{dfs}$ 的具体实现如下: + +- 如果 $\textit{state} = 0$,表示没有兵了,返回 $0$; +- 如果 $\textit{k} = 1$,表示当前是 Alice 的回合,我们需要找到一个兵,使得吃掉这个兵后的移动次数最大,即 $\text{dfs}(i, \textit{state} \oplus 2^i, \textit{k} \oplus 1) + \textit{dist}[\textit{last}][x][y]$; +- 如果 $\textit{k} = 0$,表示当前是 Bob 的回合,我们需要找到一个兵,使得吃掉这个兵后的移动次数最小,即 $\text{dfs}(i, \textit{state} \oplus 2^i, \textit{k} \oplus 1) + \textit{dist}[\textit{last}][x][y]$。 + +为了避免重复计算,我们使用记忆化搜索,即使用哈希表记录已经计算过的状态。 + +时间复杂度 $O(n \times m^2 + 2^n \times n^2)$,空间复杂度 $O(n \times m^2 + 2^n \times n)$。其中 $n$ 和 $m$ 分别为兵的数量和棋盘的大小。 #### Python3 ```python - +class Solution: + def maxMoves(self, kx: int, ky: int, positions: List[List[int]]) -> int: + @cache + def dfs(last: int, state: int, k: int) -> int: + if state == 0: + return 0 + if k: + res = 0 + for i, (x, y) in enumerate(positions): + if state >> i & 1: + t = dfs(i, state ^ (1 << i), k ^ 1) + dist[last][x][y] + if res < t: + res = t + return res + else: + res = inf + for i, (x, y) in enumerate(positions): + if state >> i & 1: + t = dfs(i, state ^ (1 << i), k ^ 1) + dist[last][x][y] + if res > t: + res = t + return res + + n = len(positions) + m = 50 + dist = [[[-1] * m for _ in range(m)] for _ in range(n + 1)] + dx = [1, 1, 2, 2, -1, -1, -2, -2] + dy = [2, -2, 1, -1, 2, -2, 1, -1] + positions.append([kx, ky]) + for i, (x, y) in enumerate(positions): + dist[i][x][y] = 0 + q = deque([(x, y)]) + step = 0 + while q: + step += 1 + for _ in range(len(q)): + x1, y1 = q.popleft() + for j in range(8): + x2, y2 = x1 + dx[j], y1 + dy[j] + if 0 <= x2 < m and 0 <= y2 < m and dist[i][x2][y2] == -1: + dist[i][x2][y2] = step + q.append((x2, y2)) + + ans = dfs(n, (1 << n) - 1, 1) + dfs.cache_clear() + return ans ``` #### Java ```java - +class Solution { + private Integer[][][] f; + private Integer[][][] dist; + private int[][] positions; + private final int[] dx = {1, 1, 2, 2, -1, -1, -2, -2}; + private final int[] dy = {2, -2, 1, -1, 2, -2, 1, -1}; + + public int maxMoves(int kx, int ky, int[][] positions) { + int n = positions.length; + final int m = 50; + dist = new Integer[n + 1][m][m]; + this.positions = positions; + for (int i = 0; i <= n; ++i) { + int x = i < n ? positions[i][0] : kx; + int y = i < n ? positions[i][1] : ky; + Deque q = new ArrayDeque<>(); + q.offer(new int[] {x, y}); + for (int step = 1; !q.isEmpty(); ++step) { + for (int k = q.size(); k > 0; --k) { + var p = q.poll(); + int x1 = p[0], y1 = p[1]; + for (int j = 0; j < 8; ++j) { + int x2 = x1 + dx[j], y2 = y1 + dy[j]; + if (x2 >= 0 && x2 < m && y2 >= 0 && y2 < m && dist[i][x2][y2] == null) { + dist[i][x2][y2] = step; + q.offer(new int[] {x2, y2}); + } + } + } + } + } + f = new Integer[n + 1][1 << n][2]; + return dfs(n, (1 << n) - 1, 1); + } + + private int dfs(int last, int state, int k) { + if (state == 0) { + return 0; + } + if (f[last][state][k] != null) { + return f[last][state][k]; + } + int res = k == 1 ? 0 : Integer.MAX_VALUE; + for (int i = 0; i < positions.length; ++i) { + int x = positions[i][0], y = positions[i][1]; + if ((state >> i & 1) == 1) { + int t = dfs(i, state ^ (1 << i), k ^ 1) + dist[last][x][y]; + res = k == 1 ? Math.max(res, t) : Math.min(res, t); + } + } + return f[last][state][k] = res; + } +} ``` #### C++ ```cpp - +class Solution { +public: + int maxMoves(int kx, int ky, vector>& positions) { + int n = positions.size(); + const int m = 50; + const int dx[8] = {1, 1, 2, 2, -1, -1, -2, -2}; + const int dy[8] = {2, -2, 1, -1, 2, -2, 1, -1}; + int dist[n + 1][m][m]; + memset(dist, -1, sizeof(dist)); + for (int i = 0; i <= n; ++i) { + int x = (i < n) ? positions[i][0] : kx; + int y = (i < n) ? positions[i][1] : ky; + queue> q; + q.push({x, y}); + dist[i][x][y] = 0; + for (int step = 1; !q.empty(); ++step) { + for (int k = q.size(); k > 0; --k) { + auto [x1, y1] = q.front(); + q.pop(); + for (int j = 0; j < 8; ++j) { + int x2 = x1 + dx[j], y2 = y1 + dy[j]; + if (x2 >= 0 && x2 < m && y2 >= 0 && y2 < m && dist[i][x2][y2] == -1) { + dist[i][x2][y2] = step; + q.push({x2, y2}); + } + } + } + } + } + + int f[n + 1][1 << n][2]; + memset(f, -1, sizeof(f)); + auto dfs = [&](auto&& dfs, int last, int state, int k) -> int { + if (state == 0) { + return 0; + } + if (f[last][state][k] != -1) { + return f[last][state][k]; + } + int res = (k == 1) ? 0 : INT_MAX; + + for (int i = 0; i < positions.size(); ++i) { + int x = positions[i][0], y = positions[i][1]; + if ((state >> i) & 1) { + int t = dfs(dfs, i, state ^ (1 << i), k ^ 1) + dist[last][x][y]; + if (k == 1) { + res = max(res, t); + } else { + res = min(res, t); + } + } + } + return f[last][state][k] = res; + }; + return dfs(dfs, n, (1 << n) - 1, 1); + } +}; ``` #### Go ```go - +func maxMoves(kx int, ky int, positions [][]int) int { + n := len(positions) + const m = 50 + dx := []int{1, 1, 2, 2, -1, -1, -2, -2} + dy := []int{2, -2, 1, -1, 2, -2, 1, -1} + dist := make([][][]int, n+1) + for i := range dist { + dist[i] = make([][]int, m) + for j := range dist[i] { + dist[i][j] = make([]int, m) + for k := range dist[i][j] { + dist[i][j][k] = -1 + } + } + } + + for i := 0; i <= n; i++ { + x := kx + y := ky + if i < n { + x = positions[i][0] + y = positions[i][1] + } + q := [][2]int{[2]int{x, y}} + dist[i][x][y] = 0 + + for step := 1; len(q) > 0; step++ { + for k := len(q); k > 0; k-- { + p := q[0] + q = q[1:] + x1, y1 := p[0], p[1] + for j := 0; j < 8; j++ { + x2 := x1 + dx[j] + y2 := y1 + dy[j] + if x2 >= 0 && x2 < m && y2 >= 0 && y2 < m && dist[i][x2][y2] == -1 { + dist[i][x2][y2] = step + q = append(q, [2]int{x2, y2}) + } + } + } + } + } + f := make([][][]int, n+1) + for i := range f { + f[i] = make([][]int, 1<>i)&1 == 1 { + t := dfs(i, state^(1< diff --git a/solution/3200-3299/3283.Maximum Number of Moves to Kill All Pawns/README_EN.md b/solution/3200-3299/3283.Maximum Number of Moves to Kill All Pawns/README_EN.md index b480dbc5c5ae9..b938aca191502 100644 --- a/solution/3200-3299/3283.Maximum Number of Moves to Kill All Pawns/README_EN.md +++ b/solution/3200-3299/3283.Maximum Number of Moves to Kill All Pawns/README_EN.md @@ -97,32 +97,281 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3200-3299/3283.Ma -### Solution 1 +### Solution 1: BFS + State Compression + Memoization + +First, we preprocess the shortest distance for each pawn to any position on the chessboard and record it in the array $\textit{dist}$, where $\textit{dist}[i][x][y]$ represents the shortest distance for the $i$-th pawn to the position $(x, y)$. + +Next, we design a function $\text{dfs}(\textit{last}, \textit{state}, \textit{k})$, where $\textit{last}$ represents the number of the last pawn eaten, $\textit{state}$ represents the current state of the remaining pawns, and $\textit{k}$ represents whether it is Alice's or Bob's turn. The function returns the maximum number of moves for the current turn. The answer is $\text{dfs}(n, 2^n-1, 1)$. Here, initially, the number of the last pawn eaten is $n$, which is also the position of the knight. + +The specific implementation of the function $\text{dfs}$ is as follows: + +- If $\textit{state} = 0$, it means there are no pawns left, return $0$; +- If $\textit{k} = 1$, it means it is Alice's turn. We need to find a pawn such that the number of moves after eating this pawn is maximized, i.e., $\text{dfs}(i, \textit{state} \oplus 2^i, \textit{k} \oplus 1) + \textit{dist}[\textit{last}][x][y]$; +- If $\textit{k} = 0$, it means it is Bob's turn. We need to find a pawn such that the number of moves after eating this pawn is minimized, i.e., $\text{dfs}(i, \textit{state} \oplus 2^i, \textit{k} \oplus 1) + \textit{dist}[\textit{last}][x][y]$. + +To avoid repeated calculations, we use memoization, i.e., using a hash table to record the states that have already been calculated. + +The time complexity is $O(n \times m^2 + 2^n \times n^2)$, and the space complexity is $O(n \times m^2 + 2^n \times n)$. Here, $n$ and $m$ represent the number of pawns and the size of the chessboard, respectively. #### Python3 ```python - +class Solution: + def maxMoves(self, kx: int, ky: int, positions: List[List[int]]) -> int: + @cache + def dfs(last: int, state: int, k: int) -> int: + if state == 0: + return 0 + if k: + res = 0 + for i, (x, y) in enumerate(positions): + if state >> i & 1: + t = dfs(i, state ^ (1 << i), k ^ 1) + dist[last][x][y] + if res < t: + res = t + return res + else: + res = inf + for i, (x, y) in enumerate(positions): + if state >> i & 1: + t = dfs(i, state ^ (1 << i), k ^ 1) + dist[last][x][y] + if res > t: + res = t + return res + + n = len(positions) + m = 50 + dist = [[[-1] * m for _ in range(m)] for _ in range(n + 1)] + dx = [1, 1, 2, 2, -1, -1, -2, -2] + dy = [2, -2, 1, -1, 2, -2, 1, -1] + positions.append([kx, ky]) + for i, (x, y) in enumerate(positions): + dist[i][x][y] = 0 + q = deque([(x, y)]) + step = 0 + while q: + step += 1 + for _ in range(len(q)): + x1, y1 = q.popleft() + for j in range(8): + x2, y2 = x1 + dx[j], y1 + dy[j] + if 0 <= x2 < m and 0 <= y2 < m and dist[i][x2][y2] == -1: + dist[i][x2][y2] = step + q.append((x2, y2)) + + ans = dfs(n, (1 << n) - 1, 1) + dfs.cache_clear() + return ans ``` #### Java ```java - +class Solution { + private Integer[][][] f; + private Integer[][][] dist; + private int[][] positions; + private final int[] dx = {1, 1, 2, 2, -1, -1, -2, -2}; + private final int[] dy = {2, -2, 1, -1, 2, -2, 1, -1}; + + public int maxMoves(int kx, int ky, int[][] positions) { + int n = positions.length; + final int m = 50; + dist = new Integer[n + 1][m][m]; + this.positions = positions; + for (int i = 0; i <= n; ++i) { + int x = i < n ? positions[i][0] : kx; + int y = i < n ? positions[i][1] : ky; + Deque q = new ArrayDeque<>(); + q.offer(new int[] {x, y}); + for (int step = 1; !q.isEmpty(); ++step) { + for (int k = q.size(); k > 0; --k) { + var p = q.poll(); + int x1 = p[0], y1 = p[1]; + for (int j = 0; j < 8; ++j) { + int x2 = x1 + dx[j], y2 = y1 + dy[j]; + if (x2 >= 0 && x2 < m && y2 >= 0 && y2 < m && dist[i][x2][y2] == null) { + dist[i][x2][y2] = step; + q.offer(new int[] {x2, y2}); + } + } + } + } + } + f = new Integer[n + 1][1 << n][2]; + return dfs(n, (1 << n) - 1, 1); + } + + private int dfs(int last, int state, int k) { + if (state == 0) { + return 0; + } + if (f[last][state][k] != null) { + return f[last][state][k]; + } + int res = k == 1 ? 0 : Integer.MAX_VALUE; + for (int i = 0; i < positions.length; ++i) { + int x = positions[i][0], y = positions[i][1]; + if ((state >> i & 1) == 1) { + int t = dfs(i, state ^ (1 << i), k ^ 1) + dist[last][x][y]; + res = k == 1 ? Math.max(res, t) : Math.min(res, t); + } + } + return f[last][state][k] = res; + } +} ``` #### C++ ```cpp - +class Solution { +public: + int maxMoves(int kx, int ky, vector>& positions) { + int n = positions.size(); + const int m = 50; + const int dx[8] = {1, 1, 2, 2, -1, -1, -2, -2}; + const int dy[8] = {2, -2, 1, -1, 2, -2, 1, -1}; + int dist[n + 1][m][m]; + memset(dist, -1, sizeof(dist)); + for (int i = 0; i <= n; ++i) { + int x = (i < n) ? positions[i][0] : kx; + int y = (i < n) ? positions[i][1] : ky; + queue> q; + q.push({x, y}); + dist[i][x][y] = 0; + for (int step = 1; !q.empty(); ++step) { + for (int k = q.size(); k > 0; --k) { + auto [x1, y1] = q.front(); + q.pop(); + for (int j = 0; j < 8; ++j) { + int x2 = x1 + dx[j], y2 = y1 + dy[j]; + if (x2 >= 0 && x2 < m && y2 >= 0 && y2 < m && dist[i][x2][y2] == -1) { + dist[i][x2][y2] = step; + q.push({x2, y2}); + } + } + } + } + } + + int f[n + 1][1 << n][2]; + memset(f, -1, sizeof(f)); + auto dfs = [&](auto&& dfs, int last, int state, int k) -> int { + if (state == 0) { + return 0; + } + if (f[last][state][k] != -1) { + return f[last][state][k]; + } + int res = (k == 1) ? 0 : INT_MAX; + + for (int i = 0; i < positions.size(); ++i) { + int x = positions[i][0], y = positions[i][1]; + if ((state >> i) & 1) { + int t = dfs(dfs, i, state ^ (1 << i), k ^ 1) + dist[last][x][y]; + if (k == 1) { + res = max(res, t); + } else { + res = min(res, t); + } + } + } + return f[last][state][k] = res; + }; + return dfs(dfs, n, (1 << n) - 1, 1); + } +}; ``` #### Go ```go - +func maxMoves(kx int, ky int, positions [][]int) int { + n := len(positions) + const m = 50 + dx := []int{1, 1, 2, 2, -1, -1, -2, -2} + dy := []int{2, -2, 1, -1, 2, -2, 1, -1} + dist := make([][][]int, n+1) + for i := range dist { + dist[i] = make([][]int, m) + for j := range dist[i] { + dist[i][j] = make([]int, m) + for k := range dist[i][j] { + dist[i][j][k] = -1 + } + } + } + + for i := 0; i <= n; i++ { + x := kx + y := ky + if i < n { + x = positions[i][0] + y = positions[i][1] + } + q := [][2]int{[2]int{x, y}} + dist[i][x][y] = 0 + + for step := 1; len(q) > 0; step++ { + for k := len(q); k > 0; k-- { + p := q[0] + q = q[1:] + x1, y1 := p[0], p[1] + for j := 0; j < 8; j++ { + x2 := x1 + dx[j] + y2 := y1 + dy[j] + if x2 >= 0 && x2 < m && y2 >= 0 && y2 < m && dist[i][x2][y2] == -1 { + dist[i][x2][y2] = step + q = append(q, [2]int{x2, y2}) + } + } + } + } + } + f := make([][][]int, n+1) + for i := range f { + f[i] = make([][]int, 1<>i)&1 == 1 { + t := dfs(i, state^(1< diff --git a/solution/3200-3299/3283.Maximum Number of Moves to Kill All Pawns/Solution.cpp b/solution/3200-3299/3283.Maximum Number of Moves to Kill All Pawns/Solution.cpp new file mode 100644 index 0000000000000..0c199646fcf66 --- /dev/null +++ b/solution/3200-3299/3283.Maximum Number of Moves to Kill All Pawns/Solution.cpp @@ -0,0 +1,57 @@ +class Solution { +public: + int maxMoves(int kx, int ky, vector>& positions) { + int n = positions.size(); + const int m = 50; + const int dx[8] = {1, 1, 2, 2, -1, -1, -2, -2}; + const int dy[8] = {2, -2, 1, -1, 2, -2, 1, -1}; + int dist[n + 1][m][m]; + memset(dist, -1, sizeof(dist)); + for (int i = 0; i <= n; ++i) { + int x = (i < n) ? positions[i][0] : kx; + int y = (i < n) ? positions[i][1] : ky; + queue> q; + q.push({x, y}); + dist[i][x][y] = 0; + for (int step = 1; !q.empty(); ++step) { + for (int k = q.size(); k > 0; --k) { + auto [x1, y1] = q.front(); + q.pop(); + for (int j = 0; j < 8; ++j) { + int x2 = x1 + dx[j], y2 = y1 + dy[j]; + if (x2 >= 0 && x2 < m && y2 >= 0 && y2 < m && dist[i][x2][y2] == -1) { + dist[i][x2][y2] = step; + q.push({x2, y2}); + } + } + } + } + } + + int f[n + 1][1 << n][2]; + memset(f, -1, sizeof(f)); + auto dfs = [&](auto&& dfs, int last, int state, int k) -> int { + if (state == 0) { + return 0; + } + if (f[last][state][k] != -1) { + return f[last][state][k]; + } + int res = (k == 1) ? 0 : INT_MAX; + + for (int i = 0; i < positions.size(); ++i) { + int x = positions[i][0], y = positions[i][1]; + if ((state >> i) & 1) { + int t = dfs(dfs, i, state ^ (1 << i), k ^ 1) + dist[last][x][y]; + if (k == 1) { + res = max(res, t); + } else { + res = min(res, t); + } + } + } + return f[last][state][k] = res; + }; + return dfs(dfs, n, (1 << n) - 1, 1); + } +}; diff --git a/solution/3200-3299/3283.Maximum Number of Moves to Kill All Pawns/Solution.go b/solution/3200-3299/3283.Maximum Number of Moves to Kill All Pawns/Solution.go new file mode 100644 index 0000000000000..db1461166676d --- /dev/null +++ b/solution/3200-3299/3283.Maximum Number of Moves to Kill All Pawns/Solution.go @@ -0,0 +1,83 @@ +func maxMoves(kx int, ky int, positions [][]int) int { + n := len(positions) + const m = 50 + dx := []int{1, 1, 2, 2, -1, -1, -2, -2} + dy := []int{2, -2, 1, -1, 2, -2, 1, -1} + dist := make([][][]int, n+1) + for i := range dist { + dist[i] = make([][]int, m) + for j := range dist[i] { + dist[i][j] = make([]int, m) + for k := range dist[i][j] { + dist[i][j][k] = -1 + } + } + } + + for i := 0; i <= n; i++ { + x := kx + y := ky + if i < n { + x = positions[i][0] + y = positions[i][1] + } + q := [][2]int{[2]int{x, y}} + dist[i][x][y] = 0 + + for step := 1; len(q) > 0; step++ { + for k := len(q); k > 0; k-- { + p := q[0] + q = q[1:] + x1, y1 := p[0], p[1] + for j := 0; j < 8; j++ { + x2 := x1 + dx[j] + y2 := y1 + dy[j] + if x2 >= 0 && x2 < m && y2 >= 0 && y2 < m && dist[i][x2][y2] == -1 { + dist[i][x2][y2] = step + q = append(q, [2]int{x2, y2}) + } + } + } + } + } + f := make([][][]int, n+1) + for i := range f { + f[i] = make([][]int, 1<>i)&1 == 1 { + t := dfs(i, state^(1< q = new ArrayDeque<>(); + q.offer(new int[] {x, y}); + for (int step = 1; !q.isEmpty(); ++step) { + for (int k = q.size(); k > 0; --k) { + var p = q.poll(); + int x1 = p[0], y1 = p[1]; + for (int j = 0; j < 8; ++j) { + int x2 = x1 + dx[j], y2 = y1 + dy[j]; + if (x2 >= 0 && x2 < m && y2 >= 0 && y2 < m && dist[i][x2][y2] == null) { + dist[i][x2][y2] = step; + q.offer(new int[] {x2, y2}); + } + } + } + } + } + f = new Integer[n + 1][1 << n][2]; + return dfs(n, (1 << n) - 1, 1); + } + + private int dfs(int last, int state, int k) { + if (state == 0) { + return 0; + } + if (f[last][state][k] != null) { + return f[last][state][k]; + } + int res = k == 1 ? 0 : Integer.MAX_VALUE; + for (int i = 0; i < positions.length; ++i) { + int x = positions[i][0], y = positions[i][1]; + if ((state >> i & 1) == 1) { + int t = dfs(i, state ^ (1 << i), k ^ 1) + dist[last][x][y]; + res = k == 1 ? Math.max(res, t) : Math.min(res, t); + } + } + return f[last][state][k] = res; + } +} diff --git a/solution/3200-3299/3283.Maximum Number of Moves to Kill All Pawns/Solution.py b/solution/3200-3299/3283.Maximum Number of Moves to Kill All Pawns/Solution.py new file mode 100644 index 0000000000000..0b32eef0b7b4f --- /dev/null +++ b/solution/3200-3299/3283.Maximum Number of Moves to Kill All Pawns/Solution.py @@ -0,0 +1,46 @@ +class Solution: + def maxMoves(self, kx: int, ky: int, positions: List[List[int]]) -> int: + @cache + def dfs(last: int, state: int, k: int) -> int: + if state == 0: + return 0 + if k: + res = 0 + for i, (x, y) in enumerate(positions): + if state >> i & 1: + t = dfs(i, state ^ (1 << i), k ^ 1) + dist[last][x][y] + if res < t: + res = t + return res + else: + res = inf + for i, (x, y) in enumerate(positions): + if state >> i & 1: + t = dfs(i, state ^ (1 << i), k ^ 1) + dist[last][x][y] + if res > t: + res = t + return res + + n = len(positions) + m = 50 + dist = [[[-1] * m for _ in range(m)] for _ in range(n + 1)] + dx = [1, 1, 2, 2, -1, -1, -2, -2] + dy = [2, -2, 1, -1, 2, -2, 1, -1] + positions.append([kx, ky]) + for i, (x, y) in enumerate(positions): + dist[i][x][y] = 0 + q = deque([(x, y)]) + step = 0 + while q: + step += 1 + for _ in range(len(q)): + x1, y1 = q.popleft() + for j in range(8): + x2, y2 = x1 + dx[j], y1 + dy[j] + if 0 <= x2 < m and 0 <= y2 < m and dist[i][x2][y2] == -1: + dist[i][x2][y2] = step + q.append((x2, y2)) + + ans = dfs(n, (1 << n) - 1, 1) + dfs.cache_clear() + return ans