← Home
For problem statement at 1000-1999/1400-1499/1420-1429/1427/problemF.txt this is a correct solution, but verifier at 1000-1999/1400-1499/1420-1429/1427/verifierF.go ends with oracle failed on case 1: runtime error: exit status 2
panic: runtime error: index out of range [19] with length 19

goroutine 1 [running]:
main.main()
	/home/ubuntu/codeforces/1000-1999/1400-1499/1420-1429/1427/1427F.go:51 +0x618

exit status 1 can you fix the verifier? package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
)

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)

	if !scanner.Scan() {
		return
	}
	n_str := scanner.Text()
	n, _ := strconv.Atoi(n_str)

	is_F := make([]bool, 6*n+1)
	for i := 0; i < 3*n; i++ {
		scanner.Scan()
		val, _ := strconv.Atoi(scanner.Text())
		is_F[val] = true
	}

	type Block struct {
		id          int
		owner       byte
		cards       []int
		parent_char int
	}

	var stack []int
	var blocks []*Block
	char_to_block := make([]int, 6*n+1)

	block_id := 0
	for i := 1; i <= 6*n; i++ {
		stack = append(stack, i)
		sz := len(stack)
		if sz >= 3 {
			c1 := stack[sz-3]
			c2 := stack[sz-2]
			c3 := stack[sz-1]
			if is_F[c1] == is_F[c2] && is_F[c2] == is_F[c3] {
				owner := byte('G')
				if is_F[c1] {
					owner = 'F'
				}
				b := &Block{
					id:    block_id,
					owner: owner,
					cards: []int{c1, c2, c3},
				}
				block_id++

				stack = stack[:sz-3]
				if len(stack) > 0 {
					b.parent_char = stack[len(stack)-1]
				}
				blocks = append(blocks, b)
				char_to_block[c1] = b.id
				char_to_block[c2] = b.id
				char_to_block[c3] = b.id
			}
		}
	}

	adj := make([][]int, 2*n)
	in_degree := make([]int, 2*n)

	for _, b := range blocks {
		if b.parent_char != 0 {
			p_id := char_to_block[b.parent_char]
			adj[b.id] = append(adj[b.id], p_id)
			in_degree[p_id]++
		}
	}

	depth := make([]int, 2*n)
	var get_depth func(int) int
	get_depth = func(u int) int {
		if depth[u] != 0 {
			return depth[u]
		}
		max_d := 0
		for _, v := range adj[u] {
			d := get_depth(v)
			if d > max_d {
				max_d = d
			}
		}
		depth[u] = max_d + 1
		return depth[u]
	}
	for i := 0; i < 2*n; i++ {
		get_depth(i)
	}

	var avail_F []int
	var avail_G []int
	for i := 0; i < 2*n; i++ {
		if in_degree[i] == 0 {
			if blocks[i].owner == 'F' {
				avail_F = append(avail_F, i)
			} else {
				avail_G = append(avail_G, i)
			}
		}
	}

	var path []int
	var dfs func(turn int) bool
	dfs = func(turn int) bool {
		if turn > 2*n {
			return true
		}
		if turn%2 == 1 {
			sort.Slice(avail_F, func(i, j int) bool {
				return depth[avail_F[i]] > depth[avail_F[j]]
			})

			curr_avail := append([]int(nil), avail_F...)
			for i := 0; i < len(curr_avail); i++ {
				u := curr_avail[i]

				idx := -1
				for j, val := range avail_F {
					if val == u {
						idx = j
						break
					}
				}
				new_avail_F := append([]int(nil), avail_F[:idx]...)
				new_avail_F = append(new_avail_F, avail_F[idx+1:]...)

				var unlocked_F, unlocked_G []int
				for _, v := range adj[u] {
					in_degree[v]--
					if in_degree[v] == 0 {
						if blocks[v].owner == 'F' {
							unlocked_F = append(unlocked_F, v)
						} else {
							unlocked_G = append(unlocked_G, v)
						}
					}
				}

				old_avail_F := avail_F
				old_avail_G := avail_G

				avail_F = append(new_avail_F, unlocked_F...)
				avail_G = append(avail_G, unlocked_G...)
				path = append(path, u)

				if dfs(turn + 1) {
					return true
				}

				path = path[:len(path)-1]
				avail_F = old_avail_F
				avail_G = old_avail_G
				for _, v := range adj[u] {
					in_degree[v]++
				}
			}
		} else {
			sort.Slice(avail_G, func(i, j int) bool {
				return depth[avail_G[i]] > depth[avail_G[j]]
			})

			curr_avail := append([]int(nil), avail_G...)
			for i := 0; i < len(curr_avail); i++ {
				u := curr_avail[i]

				idx := -1
				for j, val := range avail_G {
					if val == u {
						idx = j
						break
					}
				}
				new_avail_G := append([]int(nil), avail_G[:idx]...)
				new_avail_G = append(new_avail_G, avail_G[idx+1:]...)

				var unlocked_F, unlocked_G []int
				for _, v := range adj[u] {
					in_degree[v]--
					if in_degree[v] == 0 {
						if blocks[v].owner == 'F' {
							unlocked_F = append(unlocked_F, v)
						} else {
							unlocked_G = append(unlocked_G, v)
						}
					}
				}

				old_avail_F := avail_F
				old_avail_G := avail_G

				avail_G = append(new_avail_G, unlocked_G...)
				avail_F = append(avail_F, unlocked_F...)
				path = append(path, u)

				if dfs(turn + 1) {
					return true
				}

				path = path[:len(path)-1]
				avail_F = old_avail_F
				avail_G = old_avail_G
				for _, v := range adj[u] {
					in_degree[v]++
				}
			}
		}
		return false
	}

	dfs(1)

	for _, u := range path {
		c := blocks[u].cards
		sort.Ints(c)
		fmt.Printf("%d %d %d\n", c[0], c[1], c[2])
	}
}