1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
func maxMoves(kx int, ky int, positions [][]int) int {
n := len(positions)
pawns := make([][2]int, n)
for i, p := range positions {
pawns[i] = [2]int{p[0], p[1]}
}
// Distance matrix: dist[i][j] = distance from position i to pawn j
dist := make([][]int, n+1)
for i := range dist {
dist[i] = make([]int, n)
}
// BFS to compute minimum knight moves
bfs := func(sx, sy int) []int {
d := make([][]int, 50)
for i := range d {
d[i] = make([]int, 50)
for j := range d[i] {
d[i][j] = -1
}
}
queue := [][2]int{{sx, sy}}
d[sx][sy] = 0
res := make([]int, n)
dx := []int{-2, -2, -1, -1, 1, 1, 2, 2}
dy := []int{-1, 1, -2, 2, -2, 2, -1, 1}
for len(queue) > 0 {
curr := queue[0]
queue = queue[1:]
x, y := curr[0], curr[1]
for k := 0; k < 8; k++ {
nx, ny := x+dx[k], y+dy[k]
if nx >= 0 && nx < 50 && ny >= 0 && ny < 50 && d[nx][ny] == -1 {
d[nx][ny] = d[x][y] + 1
queue = append(queue, [2]int{nx, ny})
}
}
}
for i := 0; i < n; i++ {
res[i] = d[pawns[i][0]][pawns[i][1]]
}
return res
}
// Compute distances from initial knight position and each pawn position
dist[0] = bfs(kx, ky)
for i := 0; i < n; i++ {
dist[i+1] = bfs(pawns[i][0], pawns[i][1])
}
// Memoization map
memo := make(map[int64]int)
// DFS with memoization
var dfs func(int, int, bool) int
dfs = func(pos, mask int, alice bool) int {
key := int64(pos)<<16 | int64(mask)<<1
if alice {
key |= 1
}
if val, exists := memo[key]; exists {
return val
}
var best int
if alice {
best = -1e9
} else {
best = 1e9
}
anyMove := false
for i := 0; i < n; i++ {
if (mask & (1 << i)) == 0 {
continue
}
d := dist[pos][i]
if d < 0 {
continue
}
anyMove = true
nextVal := dfs(i+1, mask^(1<<i), !alice) + d
if alice {
best = max(best, nextVal)
} else {
best = min(best, nextVal)
}
}
if !anyMove {
memo[key] = 0
return 0
}
memo[key] = best
return best
}
return dfs(0, (1<<n)-1, true)
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
|