← Home
For problem statement at 1000-1999/1700-1799/1730-1739/1739/problemF.txt this is a correct solution, but verifier at 1000-1999/1700-1799/1730-1739/1739/verifierF.go ends with test 1 failed
input:
2
37 edk
87 ecialec
expected:kdeabcfghijl
actual:lcaiedkbfghj

exit status 1 can you fix the verifier? package main

import (
	"bufio"
	"fmt"
	"math/rand"
	"os"
	"time"
)

type Word struct {
	c   int
	seq []int
}

func scorePermutation(perm []int, words []Word) int64 {
	pos := make([]int, 12)
	for i, v := range perm {
		pos[v] = i
	}
	var total int64 = 0
	for _, w := range words {
		ok := true
		for i := 0; i+1 < len(w.seq); i++ {
			if abs(pos[w.seq[i]]-pos[w.seq[i+1]]) != 1 {
				ok = false
				break
			}
		}
		if ok {
			total += int64(w.c)
		}
	}
	return total
}

func hillClimb(perm []int, words []Word) (bestPerm []int, bestScore int64) {
	bestPerm = make([]int, 12)
	copy(bestPerm, perm)
	bestScore = scorePermutation(bestPerm, words)

	improved := true
	tmp := make([]int, 12)
	for improved {
		improved = false
		localBestDelta := int64(0)
		swapI, swapJ := -1, -1
		for i := 0; i < 12; i++ {
			for j := i + 1; j < 12; j++ {
				copy(tmp, bestPerm)
				tmp[i], tmp[j] = tmp[j], tmp[i]
				s := scorePermutation(tmp, words)
				delta := s - bestScore
				if delta > localBestDelta {
					localBestDelta = delta
					swapI, swapJ = i, j
				}
			}
		}
		if localBestDelta > 0 && swapI >= 0 {
			bestPerm[swapI], bestPerm[swapJ] = bestPerm[swapJ], bestPerm[swapI]
			bestScore += localBestDelta
			improved = true
		}
	}
	return bestPerm, bestScore
}

func randomPermutation() []int {
	p := make([]int, 12)
	for i := 0; i < 12; i++ {
		p[i] = i
	}
	for i := 11; i > 0; i-- {
		j := rand.Intn(i + 1)
		p[i], p[j] = p[j], p[i]
	}
	return p
}

func perturb(p []int) {
	// random small perturbation: either swap, reverse segment or insert
	n := len(p)
	t := rand.Intn(3)
	switch t {
	case 0:
		i := rand.Intn(n)
		j := rand.Intn(n)
		if i != j {
			p[i], p[j] = p[j], p[i]
		}
	case 1:
		i := rand.Intn(n)
		j := rand.Intn(n)
		if i > j {
			i, j = j, i
		}
		for i < j {
			p[i], p[j] = p[j], p[i]
			i++
			j--
		}
	case 2:
		i := rand.Intn(n)
		j := rand.Intn(n)
		if i == j {
			return
		}
		val := p[i]
		if i < j {
			copy(p[i:], p[i+1:j+1])
			p[j] = val
		} else {
			copy(p[j+1:], p[j:i])
			p[j] = val
		}
	}
}

func main() {
	in := bufio.NewReader(os.Stdin)
	var n int
	if _, err := fmt.Fscan(in, &n); err != nil {
		return
	}
	words := make([]Word, 0, n)
	for i := 0; i < n; i++ {
		var c int
		var s string
		fmt.Fscan(in, &c, &s)
		seq := make([]int, len(s))
		ok := true
		for j, ch := range []byte(s) {
			if ch < 'a' || ch > 'l' {
				ok = false
				break
			}
			seq[j] = int(ch - 'a')
			if j > 0 && seq[j] == seq[j-1] {
				ok = false
				break
			}
		}
		if !ok || len(seq) < 2 {
			continue
		}
		words = append(words, Word{c: c, seq: seq})
	}

	rand.Seed(time.Now().UnixNano())

	// Initial permutation heuristic: frequency-based ordering
	freq := make([]int64, 12)
	for _, w := range words {
		for i := 0; i+1 < len(w.seq); i++ {
			a, b := w.seq[i], w.seq[i+1]
			freq[a] += int64(w.c)
			freq[b] += int64(w.c)
		}
	}
	init := make([]int, 12)
	used := make([]bool, 12)
	for k := 0; k < 12; k++ {
		best := -1
		var bestF int64 = -1
		for x := 0; x < 12; x++ {
			if !used[x] && freq[x] > bestF {
				bestF = freq[x]
				best = x
			}
		}
		if best == -1 {
			for x := 0; x < 12; x++ {
				if !used[x] {
					best = x
					break
				}
			}
		}
		init[k] = best
		used[best] = true
	}

	bestPerm, bestScore := hillClimb(init, words)

	// Time-bounded multi-start with perturbations and restarts
	start := time.Now()
	timeLimit := 1200 * time.Millisecond

	// Attempt several phases: local perturbations around current best, plus random restarts
	for time.Since(start) < timeLimit {
		// Local perturbations from best
		cur := make([]int, 12)
		copy(cur, bestPerm)
		for t := 0; t < 50 && time.Since(start) < timeLimit; t++ {
			perturb(cur)
			cur2, sc := hillClimb(cur, words)
			if sc > bestScore {
				bestScore = sc
				copy(bestPerm, cur2)
				copy(cur, cur2)
			}
		}
		// Random restarts
		for r := 0; r < 5 && time.Since(start) < timeLimit; r++ {
			p := randomPermutation()
			p2, sc := hillClimb(p, words)
			if sc > bestScore {
				bestScore = sc
				copy(bestPerm, p2)
			}
		}
	}

	out := bufio.NewWriter(os.Stdout)
	for i := 0; i < 12; i++ {
		fmt.Fprintf(out, "%c", 'a'+bestPerm[i])
	}
	fmt.Fprintln(out)
	out.Flush()
}

func abs(a int) int {
	if a < 0 {
		return -a
	}
	return a
}