For problem statement at 2000-2999/2100-2199/2110-2119/2118/problemE.txt this is a correct solution, but verifier at 2000-2999/2100-2199/2110-2119/2118/verifierE.go ends with test 1 failed: penalty exceeded at (7,3): 4 (n=13 m=13)
exit status 1 can you fix the verifier? package main
import (
"bufio"
"fmt"
"os"
)
func centerSeq(l int, posFirst bool) []int {
mid := (l + 1) / 2
res := make([]int, 0, l)
res = append(res, mid)
for d := 1; len(res) < l; d++ {
if posFirst {
if mid+d <= l {
res = append(res, mid+d)
}
if mid-d >= 1 {
res = append(res, mid-d)
}
} else {
if mid-d >= 1 {
res = append(res, mid-d)
}
if mid+d <= l {
res = append(res, mid+d)
}
}
}
return res
}
func buildAnti(n, m int, rows, cols []int, inc bool) []int {
order := make([]int, 0, n*m)
for s := 0; s <= n+m-2; s++ {
lo := 0
if s-(m-1) > lo {
lo = s - (m - 1)
}
hi := n - 1
if s < hi {
hi = s
}
if inc {
for i := lo; i <= hi; i++ {
j := s - i
id := (rows[i]-1)*m + (cols[j] - 1)
order = append(order, id)
}
} else {
for i := hi; i >= lo; i-- {
j := s - i
id := (rows[i]-1)*m + (cols[j] - 1)
order = append(order, id)
}
}
}
return order
}
func getFar(order []int, p int, xOf, yOf []int, buf []int) []int {
buf = buf[:0]
px, py := xOf[p], yOf[p]
bestC, bestM := -1, -1
for _, q := range order {
dx := px - xOf[q]
if dx < 0 {
dx = -dx
}
dy := py - yOf[q]
if dy < 0 {
dy = -dy
}
c := dx
if dy > c {
c = dy
}
man := dx + dy
if c > bestC || (c == bestC && man > bestM) {
bestC, bestM = c, man
buf = buf[:0]
buf = append(buf, q)
} else if c == bestC && man == bestM {
buf = append(buf, q)
}
}
return buf
}
func validate(order []int, xOf, yOf []int) bool {
n := len(order)
cnt := make([]uint8, len(xOf))
buf := make([]int, 0, n)
for i, p := range order {
if i == 0 {
cnt[p]++
if cnt[p] > 3 {
return false
}
continue
}
far := getFar(order[:i], p, xOf, yOf, buf)
buf = far
for _, q := range far {
cnt[q]++
if cnt[q] > 3 {
return false
}
}
}
return true
}
func evalAdd(order []int, cnt []uint8, p int, xOf, yOf []int, buf []int) (bool, uint8, int, int) {
if len(order) == 0 {
return true, 1, 0, 1
}
far := getFar(order, p, xOf, yOf, buf)
maxNew := uint8(0)
num3 := 0
for _, q := range far {
if cnt[q] == 3 {
return false, 0, 0, 0
}
nc := cnt[q] + 1
if nc > maxNew {
maxNew = nc
}
if nc == 3 {
num3++
}
}
return true, maxNew, num3, len(far)
}
func applyAdd(order *[]int, cnt []uint8, p int, xOf, yOf []int, buf []int) {
if len(*order) == 0 {
cnt[p]++
*order = append(*order, p)
return
}
far := getFar(*order, p, xOf, yOf, buf)
for _, q := range far {
cnt[q]++
}
*order = append(*order, p)
}
func better(v1 bool, m1 uint8, c31, f1 int, v2 bool, m2 uint8, c32, f2 int, preferFirst bool) bool {
if !v1 {
return false
}
if !v2 {
return true
}
if m1 != m2 {
return m1 < m2
}
if c31 != c32 {
return c31 < c32
}
if f1 != f2 {
return f1 < f2
}
return preferFirst
}
func greedyAnti(n, m int, rows, cols []int, xOf, yOf []int, preferLeft bool) ([]int, bool) {
cnt := make([]uint8, n*m)
order := make([]int, 0, n*m)
buf := make([]int, 0, n*m)
for s := 0; s <= n+m-2; s++ {
lo := 0
if s-(m-1) > lo {
lo = s - (m - 1)
}
hi := n - 1
if s < hi {
hi = s
}
if lo > hi {
continue
}
diag := make([]int, 0, hi-lo+1)
for i := lo; i <= hi; i++ {
j := s - i
id := (rows[i]-1)*m + (cols[j] - 1)
diag = append(diag, id)
}
l, r := 0, len(diag)-1
for l <= r {
if l == r {
ok, _, _, _ := evalAdd(order, cnt, diag[l], xOf, yOf, buf)
if !ok {
return nil, false
}
applyAdd(&order, cnt, diag[l], xOf, yOf, buf)
l++
r--
continue
}
pL := diag[l]
pR := diag[r]
vL, mL, c3L, fL := evalAdd(order, cnt, pL, xOf, yOf, buf)
vR, mR, c3R, fR := evalAdd(order, cnt, pR, xOf, yOf, buf)
if !vL && !vR {
return nil, false
}
if better(vL, mL, c3L, fL, vR, mR, c3R, fR, preferLeft) {
applyAdd(&order, cnt, pL, xOf, yOf, buf)
l++
} else {
applyAdd(&order, cnt, pR, xOf, yOf, buf)
r--
}
}
}
return order, true
}
func solveCase(n, m int) []int {
N := n * m
xOf := make([]int, N)
yOf := make([]int, N)
for i := 1; i <= n; i++ {
base := (i - 1) * m
for j := 1; j <= m; j++ {
id := base + (j - 1)
xOf[id] = i
yOf[id] = j
}
}
signs := [][2]bool{
{true, true},
{true, false},
{false, true},
{false, false},
}
for _, sg := range signs {
rows := centerSeq(n, sg[0])
cols := centerSeq(m, sg[1])
ord := buildAnti(n, m, rows, cols, true)
if validate(ord, xOf, yOf) {
return ord
}
ord = buildAnti(n, m, rows, cols, false)
if validate(ord, xOf, yOf) {
return ord
}
}
for _, sg := range signs {
rows := centerSeq(n, sg[0])
cols := centerSeq(m, sg[1])
if ord, ok := greedyAnti(n, m, rows, cols, xOf, yOf, true); ok {
return ord
}
if ord, ok := greedyAnti(n, m, rows, cols, xOf, yOf, false); ok {
return ord
}
}
rows := centerSeq(n, true)
cols := centerSeq(m, true)
return buildAnti(n, m, rows, cols, true)
}
func main() {
in := bufio.NewReaderSize(os.Stdin, 1<<20)
out := bufio.NewWriterSize(os.Stdout, 1<<20)
defer out.Flush()
var t int
fmt.Fscan(in, &t)
for ; t > 0; t-- {
var n, m int
fmt.Fscan(in, &n, &m)
order := solveCase(n, m)
for _, id := range order {
x := id/m + 1
y := id%m + 1
fmt.Fprintln(out, x, y)
}
}
}