For problem statement at 1000-1999/1200-1299/1200-1209/1201/problemE2.txt this is a correct solution, but verifier at 1000-1999/1200-1299/1200-1209/1201/verifierE2.go ends with Problem E2 is interactive and cannot be automatically verified. can you fix the verifier? package main
import (
"bufio"
"fmt"
"io"
"os"
)
const (
Draw uint8 = 0
White uint8 = 1
Black uint8 = 2
)
var (
n, m int
N int
NN int
moves [][]int
moveCnt []uint8
wTarget int
bTarget int
isW []bool
isB []bool
attW []bool
attB []bool
result []uint8
rem []uint8
)
func idx(turn, w, b int) int {
return turn*NN + w*N + b
}
func decode(id int) (int, int, int) {
turn := 0
if id >= NN {
turn = 1
id -= NN
}
w := id / N
b := id % N
return turn, w, b
}
func terminal(turn, w, b int) uint8 {
if w == b {
if turn == 0 {
return Black
}
return White
}
sw := isW[w] && !attW[b]
sb := isB[b] && !attB[w]
if sw && sb {
if turn == 0 {
return Black
}
return White
}
if sw {
return White
}
if sb {
return Black
}
return Draw
}
func initialWinner(w, b int) uint8 {
sw := isW[w] && !attW[b]
sb := isB[b] && !attB[w]
if sw && !sb {
return White
}
if sb && !sw {
return Black
}
if sw && sb {
return White
}
if w == b {
return White
}
return Draw
}
func buildMoves() {
dx := [8]int{1, 1, -1, -1, 2, 2, -2, -2}
dy := [8]int{2, -2, 2, -2, 1, -1, 1, -1}
moves = make([][]int, N)
moveCnt = make([]uint8, N)
isW = make([]bool, N)
isB = make([]bool, N)
attW = make([]bool, N)
attB = make([]bool, N)
isW[wTarget] = true
isB[bTarget] = true
for r := 0; r < n; r++ {
for c := 0; c < m; c++ {
p := r*m + c
list := make([]int, 0, 8)
for k := 0; k < 8; k++ {
nr := r + dx[k]
nc := c + dy[k]
if nr >= 0 && nr < n && nc >= 0 && nc < m {
q := nr*m + nc
list = append(list, q)
if q == wTarget {
attW[p] = true
}
if q == bTarget {
attB[p] = true
}
}
}
moves[p] = list
moveCnt[p] = uint8(len(list))
}
}
}
func solve() {
total := 2 * NN
result = make([]uint8, total)
rem = make([]uint8, total)
queue := make([]int32, 0, total/8+1)
for w := 0; w < N; w++ {
lw := moveCnt[w]
base0 := w * N
base1 := NN + w*N
for b := 0; b < N; b++ {
id0 := base0 + b
t0 := terminal(0, w, b)
if t0 != Draw {
result[id0] = t0
queue = append(queue, int32(id0))
} else if lw == 0 {
result[id0] = Black
queue = append(queue, int32(id0))
} else {
rem[id0] = lw
}
id1 := base1 + b
t1 := terminal(1, w, b)
lb := moveCnt[b]
if t1 != Draw {
result[id1] = t1
queue = append(queue, int32(id1))
} else if lb == 0 {
result[id1] = White
queue = append(queue, int32(id1))
} else {
rem[id1] = lb
}
}
}
for head := 0; head < len(queue); head++ {
s := int(queue[head])
g := result[s]
turn, w, b := decode(s)
if turn == 0 {
base := NN + w*N
for _, bp := range moves[b] {
p := base + bp
if result[p] != Draw {
continue
}
if g == Black {
result[p] = Black
queue = append(queue, int32(p))
} else {
rem[p]--
if rem[p] == 0 {
result[p] = White
queue = append(queue, int32(p))
}
}
}
} else {
for _, wp := range moves[w] {
p := wp*N + b
if result[p] != Draw {
continue
}
if g == White {
result[p] = White
queue = append(queue, int32(p))
} else {
rem[p]--
if rem[p] == 0 {
result[p] = Black
queue = append(queue, int32(p))
}
}
}
}
}
}
func better(my, a, b uint8) bool {
if a == b {
return false
}
if my == White {
if a == White {
return true
}
if a == Draw && b == Black {
return true
}
return false
}
if a == Black {
return true
}
if a == Draw && b == White {
return true
}
return false
}
func chooseMove(turn, w, b int, my uint8) (int, bool) {
bestPos := -1
bestRes := uint8(0)
if turn == 0 {
for _, nw := range moves[w] {
r := terminal(1, nw, b)
if r == Draw {
r = result[idx(1, nw, b)]
}
if bestPos == -1 || better(my, r, bestRes) {
bestPos = nw
bestRes = r
if r == my {
break
}
}
}
} else {
for _, nb := range moves[b] {
r := terminal(0, w, nb)
if r == Draw {
r = result[idx(0, w, nb)]
}
if bestPos == -1 || better(my, r, bestRes) {
bestPos = nb
bestRes = r
if r == my {
break
}
}
}
}
if bestPos == -1 {
return 0, false
}
return bestPos, true
}
func printPos(out *bufio.Writer, p int) {
fmt.Fprintln(out, p/m+1, p%m+1)
out.Flush()
}
func main() {
in := bufio.NewReader(os.Stdin)
out := bufio.NewWriter(os.Stdout)
defer out.Flush()
var x1, y1, x2, y2 int
if _, err := fmt.Fscan(in, &n, &m, &x1, &y1, &x2, &y2); err != nil {
if err == io.EOF {
return
}
return
}
N = n * m
NN = N * N
wTarget = (n/2-1)*m + (m/2 - 1)
bTarget = (n / 2 * m) + (m/2 - 1)
w := (x1-1)*m + (y1 - 1)
b := (x2-1)*m + (y2 - 1)
buildMoves()
solve()
my := initialWinner(w, b)
if my == Draw {
my = result[idx(0, w, b)]
}
if my == Draw {
my = White
}
if my == White {
fmt.Fprintln(out, "White")
} else {
fmt.Fprintln(out, "Black")
}
out.Flush()
if initialWinner(w, b) != Draw {
return
}
turn := 0
for {
if (turn == 0 && my == White) || (turn == 1 && my == Black) {
npos, ok := chooseMove(turn, w, b, my)
if !ok {
return
}
if turn == 0 {
w = npos
} else {
b = npos
}
printPos(out, npos)
turn ^= 1
if terminal(turn, w, b) != Draw {
return
}
} else {
var xr, yr int
if _, err := fmt.Fscan(in, &xr, &yr); err != nil {
return
}
if xr < 0 || yr < 0 {
return
}
p := (xr-1)*m + (yr - 1)
if turn == 0 {
w = p
} else {
b = p
}
turn ^= 1
if terminal(turn, w, b) != Draw {
return
}
}
}
}