← Home
For problem statement at 1000-1999/1100-1199/1140-1149/1147/problemE.txt this is a correct solution, but verifier at 1000-1999/1100-1199/1140-1149/1147/verifierE.go ends with Problem E is interactive and cannot be automatically verified. can you fix the verifier? package main

import (
	"bufio"
	"fmt"
	"os"
)

type Part []int

type Component struct {
	parts []Part
	id    int
}

type Query struct {
	u, v int
	ref  interface{}
}

func main() {
	reader := bufio.NewReader(os.Stdin)
	writer := bufio.NewWriter(os.Stdout)
	defer writer.Flush()

	var n int
	if _, err := fmt.Fscanf(reader, "%d\n", &n); err != nil {
		return
	}

	components := make([]*Component, n)
	for i := 0; i < n; i++ {
		components[i] = &Component{
			parts: []Part{{i + 1}},
			id:    i,
		}
	}

	type Partial struct {
		part       Part
		testedWith int
	}
	var partials []Partial

	for batch := 0; batch < 7; batch++ {
		if len(components) == 1 && len(partials) == 0 {
			break
		}

		var t3, t2, t1 []*Component
		for _, c := range components {
			if len(c.parts) == 3 {
				t3 = append(t3, c)
			} else if len(c.parts) == 2 {
				t2 = append(t2, c)
			} else {
				t1 = append(t1, c)
			}
		}

		var hub *Component
		if len(t3) > 0 {
			hub = t3[0]
			for i := 1; i < len(t3); i++ {
				if len(t3[i].parts[0]) > len(hub.parts[0]) {
					hub = t3[i]
				}
			}
		}

		var queries []Query
		used := make([]bool, n+1)

		getAvail := func(part Part, count int) []int {
			var res []int
			for _, v := range part {
				if !used[v] {
					res = append(res, v)
					if len(res) == count {
						break
					}
				}
			}
			return res
		}

		markUsed := func(vs ...int) {
			for _, v := range vs {
				used[v] = true
			}
		}

		type Task struct {
			typ  int
			args []interface{}
		}
		var tasks []Task

		var nextPartials []Partial
		for _, p := range partials {
			if hub != nil {
				h2 := 1
				if p.testedWith == 1 {
					h2 = 2
				}
				hAvail := getAvail(hub.parts[h2], 1)
				pAvail := getAvail(p.part, 1)
				if len(hAvail) > 0 && len(pAvail) > 0 {
					queries = append(queries, Query{hAvail[0], pAvail[0], nil})
					markUsed(hAvail[0], pAvail[0])
					tasks = append(tasks, Task{10, []interface{}{p, hAvail[0], pAvail[0], h2}})
					continue
				}
			}
			nextPartials = append(nextPartials, p)
		}
		partials = nextPartials

		var unmergedT3 []*Component
		for _, c := range t3 {
			if c == hub {
				continue
			}
			h1 := getAvail(hub.parts[0], 2)
			h2 := getAvail(hub.parts[1], 1)
			d1 := getAvail(c.parts[0], 1)
			d2 := getAvail(c.parts[1], 1)
			d3 := getAvail(c.parts[2], 1)
			if len(h1) == 2 && len(h2) == 1 && len(d1) == 1 && len(d2) == 1 && len(d3) == 1 {
				queries = append(queries, Query{h1[0], d1[0], nil}, Query{h1[1], d2[0], nil}, Query{h2[0], d3[0], nil})
				markUsed(h1[0], h1[1], h2[0], d1[0], d2[0], d3[0])
				tasks = append(tasks, Task{3, []interface{}{c, h1[0], d1[0], h1[1], d2[0], h2[0], d3[0]}})
			} else {
				unmergedT3 = append(unmergedT3, c)
			}
		}

		var unmergedT2 []*Component
		for _, c := range t2 {
			merged := false
			if hub != nil {
				canAbsorb := true
				var tQueries []Query
				var tUsed []int
				var tArgs []interface{}
				for _, part := range c.parts {
					if len(part) >= 2 {
						h1 := getAvail(hub.parts[0], 1)
						h2 := getAvail(hub.parts[1], 1)
						p := getAvail(part, 2)
						if len(h1) > 0 && len(h2) > 0 && len(p) == 2 {
							tQueries = append(tQueries, Query{h1[0], p[0], nil}, Query{h2[0], p[1], nil})
							tUsed = append(tUsed, h1[0], h2[0], p[0], p[1])
							markUsed(h1[0], h2[0], p[0], p[1])
							tArgs = append(tArgs, part, 2, h1[0], p[0], h2[0], p[1])
						} else {
							canAbsorb = false
							break
						}
					} else {
						h1 := getAvail(hub.parts[0], 1)
						p := getAvail(part, 1)
						if len(h1) > 0 && len(p) > 0 {
							tQueries = append(tQueries, Query{h1[0], p[0], nil})
							tUsed = append(tUsed, h1[0], p[0])
							markUsed(h1[0], p[0])
							tArgs = append(tArgs, part, 1, h1[0], p[0])
						} else {
							canAbsorb = false
							break
						}
					}
				}
				if canAbsorb {
					queries = append(queries, tQueries...)
					tasks = append(tasks, Task{4, tArgs})
					merged = true
				} else {
					for _, u := range tUsed {
						used[u] = false
					}
				}
			}
			if !merged {
				unmergedT2 = append(unmergedT2, c)
			}
		}

		var unmergedT1 []*Component
		for _, c := range t1 {
			merged := false
			if hub != nil {
				part := c.parts[0]
				if len(part) >= 2 {
					h1 := getAvail(hub.parts[0], 1)
					h2 := getAvail(hub.parts[1], 1)
					p := getAvail(part, 2)
					if len(h1) > 0 && len(h2) > 0 && len(p) == 2 {
						queries = append(queries, Query{h1[0], p[0], nil}, Query{h2[0], p[1], nil})
						markUsed(h1[0], h2[0], p[0], p[1])
						tasks = append(tasks, Task{5, []interface{}{part, h1[0], p[0], h2[0], p[1]}})
						merged = true
					}
				} else {
					h1 := getAvail(hub.parts[0], 1)
					p := getAvail(part, 1)
					if len(h1) > 0 && len(p) > 0 {
						queries = append(queries, Query{h1[0], p[0], nil})
						markUsed(h1[0], p[0])
						tasks = append(tasks, Task{6, []interface{}{part, h1[0], p[0]}})
						merged = true
					}
				}
			}
			if !merged {
				unmergedT1 = append(unmergedT1, c)
			}
		}

		for i := 0; i+1 < len(unmergedT2); i += 2 {
			c, d := unmergedT2[i], unmergedT2[i+1]
			c1 := getAvail(c.parts[0], 1)
			c2 := getAvail(c.parts[1], 1)
			d1 := getAvail(d.parts[0], 1)
			d2 := getAvail(d.parts[1], 1)
			if len(c1) > 0 && len(c2) > 0 && len(d1) > 0 && len(d2) > 0 {
				queries = append(queries, Query{c1[0], d1[0], nil}, Query{c2[0], d2[0], nil})
				markUsed(c1[0], c2[0], d1[0], d2[0])
				tasks = append(tasks, Task{2, []interface{}{c, d, c1[0], d1[0], c2[0], d2[0]}})
			}
		}
		for i := 0; i+1 < len(unmergedT1); i += 2 {
			c, d := unmergedT1[i], unmergedT1[i+1]
			c1 := getAvail(c.parts[0], 1)
			d1 := getAvail(d.parts[0], 1)
			if len(c1) > 0 && len(d1) > 0 {
				queries = append(queries, Query{c1[0], d1[0], nil})
				markUsed(c1[0], d1[0])
				tasks = append(tasks, Task{1, []interface{}{c, d, c1[0], d1[0]}})
			}
		}

		if len(queries) == 0 {
			break
		}

		fmt.Fprintf(writer, "%d\n", len(queries))
		for _, q := range queries {
			fmt.Fprintf(writer, "%d %d\n", q.u, q.v)
		}
		writer.Flush()

		results := make([]int, len(queries))
		for i := 0; i < len(queries); i++ {
			fmt.Fscanf(reader, "%d", &results[i])
		}

		resMap := make(map[string]int)
		for i, q := range queries {
			resMap[fmt.Sprintf("%d_%d", q.u, q.v)] = results[i]
		}

		checkRes := func(u, v int) int {
			if val, ok := resMap[fmt.Sprintf("%d_%d", u, v)]; ok {
				return val
			}
			return resMap[fmt.Sprintf("%d_%d", v, u)]
		}

		var nextComponents []*Component
		if hub != nil {
			nextComponents = append(nextComponents, hub)
		}
		mergedComps := make(map[int]bool)

		for _, t := range tasks {
			if t.typ == 1 {
				c := t.args[0].(*Component)
				d := t.args[1].(*Component)
				mergedComps[c.id] = true
				mergedComps[d.id] = true
				res := checkRes(t.args[2].(int), t.args[3].(int))
				if res == 1 {
					c.parts[0] = append(c.parts[0], d.parts[0]...)
					nextComponents = append(nextComponents, c)
				} else {
					c.parts = append(c.parts, d.parts[0])
					nextComponents = append(nextComponents, c)
				}
			} else if t.typ == 2 {
				c := t.args[0].(*Component)
				d := t.args[1].(*Component)
				mergedComps[c.id] = true
				mergedComps[d.id] = true
				r1 := checkRes(t.args[2].(int), t.args[3].(int))
				r2 := checkRes(t.args[4].(int), t.args[5].(int))
				if r1 == 1 && r2 == 1 {
					c.parts[0] = append(c.parts[0], d.parts[0]...)
					c.parts[1] = append(c.parts[1], d.parts[1]...)
				} else if r1 == 1 && r2 == 0 {
					c.parts[0] = append(c.parts[0], d.parts[0]...)
					c.parts = append(c.parts, d.parts[1])
				} else if r1 == 0 && r2 == 1 {
					c.parts[0] = append(c.parts[0], d.parts[1]...)
					c.parts = append(c.parts, d.parts[0])
				} else {
					c.parts[0] = append(c.parts[0], d.parts[1]...)
					c.parts[1] = append(c.parts[1], d.parts[0]...)
				}
				nextComponents = append(nextComponents, c)
			} else if t.typ == 3 {
				c := t.args[0].(*Component)
				mergedComps[c.id] = true
				r1 := checkRes(t.args[1].(int), t.args[2].(int))
				r2 := checkRes(t.args[3].(int), t.args[4].(int))
				r3 := checkRes(t.args[5].(int), t.args[6].(int))

				var m1, m2, m3 int
				if r1 == 1 {
					m1 = 0
				} else if r2 == 1 {
					m1 = 1
				} else {
					m1 = 2
				}

				if r3 == 1 {
					m3 = 2
				} else {
					if m1 == 2 {
						m3 = 1
					} else {
						m3 = 2
					}
				}
				m2 = 3 - m1 - m3
				hub.parts[m1] = append(hub.parts[m1], c.parts[0]...)
				hub.parts[m2] = append(hub.parts[m2], c.parts[1]...)
				hub.parts[m3] = append(hub.parts[m3], c.parts[2]...)
			} else if t.typ == 4 {
				args := t.args
				idx := 0
				for idx < len(args) {
					part := args[idx].(Part)
					cnt := args[idx+1].(int)
					if cnt == 2 {
						r1 := checkRes(args[idx+2].(int), args[idx+3].(int))
						r2 := checkRes(args[idx+4].(int), args[idx+5].(int))
						if r1 == 1 {
							hub.parts[0] = append(hub.parts[0], part...)
						} else if r2 == 1 {
							hub.parts[1] = append(hub.parts[1], part...)
						} else {
							hub.parts[2] = append(hub.parts[2], part...)
						}
						idx += 6
					} else {
						r1 := checkRes(args[idx+2].(int), args[idx+3].(int))
						if r1 == 1 {
							hub.parts[0] = append(hub.parts[0], part...)
						} else {
							partials = append(partials, Partial{part, 0})
						}
						idx += 4
					}
				}
			} else if t.typ == 5 {
				part := t.args[0].(Part)
				r1 := checkRes(t.args[1].(int), t.args[2].(int))
				r2 := checkRes(t.args[3].(int), t.args[4].(int))
				if r1 == 1 {
					hub.parts[0] = append(hub.parts[0], part...)
				} else if r2 == 1 {
					hub.parts[1] = append(hub.parts[1], part...)
				} else {
					hub.parts[2] = append(hub.parts[2], part...)
				}
			} else if t.typ == 6 {
				part := t.args[0].(Part)
				r1 := checkRes(t.args[1].(int), t.args[2].(int))
				if r1 == 1 {
					hub.parts[0] = append(hub.parts[0], part...)
				} else {
					partials = append(partials, Partial{part, 0})
				}
			} else if t.typ == 10 {
				p := t.args[0].(Partial)
				r := checkRes(t.args[1].(int), t.args[2].(int))
				h2 := t.args[3].(int)
				if r == 1 {
					hub.parts[h2] = append(hub.parts[h2], p.part...)
				} else {
					rem := 3 - 0 - h2
					hub.parts[rem] = append(hub.parts[rem], p.part...)
				}
			}
		}

		for _, c := range unmergedT3 {
			if !mergedComps[c.id] {
				nextComponents = append(nextComponents, c)
			}
		}
		for _, c := range unmergedT2 {
			if !mergedComps[c.id] {
				nextComponents = append(nextComponents, c)
			}
		}
		for _, c := range unmergedT1 {
			if !mergedComps[c.id] {
				nextComponents = append(nextComponents, c)
			}
		}

		if hub != nil {
			for i := 0; i < len(hub.parts); i++ {
				for j := i + 1; j < len(hub.parts); j++ {
					if len(hub.parts[i]) < len(hub.parts[j]) {
						hub.parts[i], hub.parts[j] = hub.parts[j], hub.parts[i]
					}
				}
			}
		}

		components = nextComponents
	}

	ans := make([]Part, 3)
	if len(components) > 0 {
		for i, p := range components[0].parts {
			if i < 3 {
				ans[i] = p
			}
		}
	}
	for i := 0; i < 3; i++ {
		for j, v := range ans[i] {
			if j > 0 {
				fmt.Fprintf(writer, " ")
			}
			fmt.Fprintf(writer, "%d", v)
		}
		fmt.Fprintf(writer, "\n")
	}
}