← Home
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)
		}
	}
}