Skip to content

Commit 6dc3879

Browse files
authored
Create 3283-maximum-number-of-moves-to-kill-all-pawns.js
1 parent 2602592 commit 6dc3879

File tree

1 file changed

+126
-0
lines changed

1 file changed

+126
-0
lines changed
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
/**
2+
* @param {number} kx
3+
* @param {number} ky
4+
* @param {number[][]} positions
5+
* @return {number}
6+
*/
7+
var maxMoves = function (kx, ky, positions) {
8+
//alice goes first
9+
//alice wants to maximize result
10+
11+
//add the starting position
12+
positions.unshift([kx, ky])
13+
14+
let dp = new Float64Array(positions.length * 2 ** positions.length)
15+
let degreesBetweenPawnPairs = new Float64Array(
16+
positions.length * positions.length,
17+
)
18+
19+
computeAllDegreesBetweenPawns()
20+
21+
//if the mask is equal to this, we've visited all pawns
22+
let targetMask = (1 << positions.length) - 1
23+
24+
//alice starts, so we set maximize to true
25+
return dfs(0, true, 1)
26+
27+
function dfs(pawn1Idx, maximize, mask) {
28+
if (mask === targetMask) {
29+
return 0
30+
}
31+
32+
let dpIdx = pawn1Idx * 2 ** positions.length + mask
33+
if (dp[dpIdx] > 0) {
34+
return dp[dpIdx] - 1
35+
}
36+
37+
let best = Infinity
38+
let worst = 0
39+
40+
for (let pawn2Idx = 0; pawn2Idx < positions.length; ++pawn2Idx) {
41+
if (mask & (1 << pawn2Idx)) {
42+
continue
43+
}
44+
45+
let cur = degreeBetween(pawn1Idx, pawn2Idx)
46+
cur += dfs(pawn2Idx, !maximize, mask | (1 << pawn2Idx))
47+
48+
best = Math.min(best, cur)
49+
worst = Math.max(worst, cur)
50+
}
51+
52+
let ret
53+
if (maximize) {
54+
ret = worst
55+
} else {
56+
ret = best
57+
}
58+
59+
dp[dpIdx] = ret + 1
60+
return ret
61+
}
62+
63+
function computeAllDegreesBetweenPawns() {
64+
let targets = new Map(positions.map(([x, y], idx) => [y * 50 + x, idx]))
65+
66+
let visited = new Array(50 * 50).fill(0)
67+
const MOVES = [
68+
[2, 1],
69+
[-2, 1],
70+
[2, -1],
71+
[-2, -1],
72+
[1, -2],
73+
[1, 2],
74+
[-1, 2],
75+
[-1, -2],
76+
]
77+
78+
for (let i = 0; i < positions.length; ++i) {
79+
let q = [positions[i]]
80+
let q2 = []
81+
let steps = 0
82+
83+
visited[positions[i][1] * 50 + positions[i][0]] = i
84+
85+
while (q.length) {
86+
let [x, y] = q.pop()
87+
88+
{
89+
let dpIdx = y * 50 + x
90+
if (targets.has(dpIdx)) {
91+
let v1 = i
92+
let v2 = targets.get(dpIdx)
93+
degreesBetweenPawnPairs[v1 * positions.length + v2] = steps
94+
degreesBetweenPawnPairs[v2 * positions.length + v1] = steps
95+
}
96+
}
97+
98+
for (let [offx, offy] of MOVES) {
99+
let newX = x + offx
100+
let newY = y + offy
101+
102+
if (newX >= 50 || newY >= 50 || newX < 0 || newY < 0) {
103+
continue
104+
}
105+
let visitedDpIdx = newY * 50 + newX
106+
if (visited[visitedDpIdx] === i) {
107+
continue
108+
}
109+
visited[visitedDpIdx] = i
110+
q2.push([newX, newY])
111+
}
112+
113+
if (!q.length) {
114+
;[q2, q] = [q, q2]
115+
++steps
116+
}
117+
}
118+
}
119+
}
120+
121+
function degreeBetween(i, j) {
122+
return degreesBetweenPawnPairs[i * positions.length + j]
123+
}
124+
}
125+
126+

0 commit comments

Comments
 (0)