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
|
func minPushBox(grid [][]byte) int {
m, n := len(grid), len(grid[0])
var bx, by, px, py, tx, ty int
for i := 0; i < m; i++ {
for j := 0; j < n; j++ {
switch grid[i][j] {
case 'B':
bx, by = i, j
case 'S':
px, py = i, j
case 'T':
tx, ty = i, j
}
}
}
dirs := [][]int{{0,1},{0,-1},{1,0},{-1,0}}
canReach := func(sx, sy, ex, ey, bx, by int) bool {
vis := make([][]bool, m)
for i := range vis { vis[i] = make([]bool, n) }
q := [][2]int{{sx, sy}}
vis[sx][sy] = true
for len(q) > 0 {
x, y := q[0][0], q[0][1]
q = q[1:]
if x == ex && y == ey { return true }
for _, d := range dirs {
nx, ny := x+d[0], y+d[1]
if nx >= 0 && nx < m && ny >= 0 && ny < n &&
!vis[nx][ny] && grid[nx][ny] != '#' &&
!(nx == bx && ny == by) {
vis[nx][ny] = true
q = append(q, [2]int{nx, ny})
}
}
}
return false
}
type state struct{ bx, by, px, py int }
vis := map[state]bool{}
q := []struct{ bx, by, px, py, moves int }{{bx, by, px, py, 0}}
vis[state{bx, by, px, py}] = true
for len(q) > 0 {
s := q[0]; q = q[1:]
if s.bx == tx && s.by == ty { return s.moves }
for _, d := range dirs {
nbx, nby := s.bx+d[0], s.by+d[1]
ppx, ppy := s.bx-d[0], s.by-d[1]
if nbx < 0 || nbx >= m || nby < 0 || nby >= n || grid[nbx][nby] == '#' { continue }
if ppx < 0 || ppx >= m || ppy < 0 || ppy >= n || grid[ppx][ppy] == '#' { continue }
if !canReach(s.px, s.py, ppx, ppy, s.bx, s.by) { continue }
ns := state{nbx, nby, s.bx, s.by}
if vis[ns] { continue }
vis[ns] = true
q = append(q, struct{ bx, by, px, py, moves int }{nbx, nby, s.bx, s.by, s.moves + 1})
}
}
return -1
}
|