-
-
Notifications
You must be signed in to change notification settings - Fork 8.8k
/
Copy pathSolution.go
76 lines (75 loc) · 1.73 KB
/
Solution.go
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
const (
hole = 0
mouseStart = 1
catStart = 2
mouseTurn = 0
catTurn = 1
mouseWin = 1
catWin = 2
tie = 0
)
func catMouseGame(graph [][]int) int {
res := [50][50][2]int{}
degree := [50][50][2]int{}
n := len(graph)
for i := 0; i < n; i++ {
for j := 1; j < n; j++ {
degree[i][j][mouseTurn] = len(graph[i])
degree[i][j][catTurn] = len(graph[j])
}
for _, j := range graph[hole] {
degree[i][j][catTurn]--
}
}
type tuple struct{ m, c, t int }
q := []tuple{}
for j := 1; j < n; j++ {
res[0][j][mouseTurn], res[0][j][catTurn] = mouseWin, mouseWin
q = append(q, tuple{0, j, mouseTurn})
q = append(q, tuple{0, j, catTurn})
}
for i := 1; i < n; i++ {
res[i][i][mouseTurn], res[i][i][catTurn] = catWin, catWin
q = append(q, tuple{i, i, mouseTurn})
q = append(q, tuple{i, i, catTurn})
}
getPrevStates := func(m, c, t int) []tuple {
pre := []tuple{}
pt := t ^ 1
if pt == catTurn {
for _, pc := range graph[c] {
if pc != hole {
pre = append(pre, tuple{m, pc, pt})
}
}
} else {
for _, pm := range graph[m] {
pre = append(pre, tuple{pm, c, pt})
}
}
return pre
}
for len(q) > 0 {
state := q[0]
m, c, t := state.m, state.c, state.t
q = q[1:]
x := res[m][c][t]
for _, prevState := range getPrevStates(m, c, t) {
pm, pc, pt := prevState.m, prevState.c, prevState.t
if res[pm][pc][pt] == tie {
win := (x == mouseWin && pt == mouseTurn) || (x == catWin && pt == catTurn)
if win {
res[pm][pc][pt] = x
q = append(q, tuple{pm, pc, pt})
} else {
degree[pm][pc][pt]--
if degree[pm][pc][pt] == 0 {
res[pm][pc][pt] = x
q = append(q, tuple{pm, pc, pt})
}
}
}
}
}
return res[mouseStart][catStart][mouseTurn]
}