← Home
For problem statement at 0-999/300-399/330-339/339/problemE.txt this is a correct solution, but verifier at 0-999/300-399/330-339/339/verifierE.go ends with All 100 tests passed can you fix the verifier? package main

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

type Pair struct {
	l, r int
}

type Cand struct {
	l, r int
	s    int
}

var path []Pair

func isSorted(a []int) bool {
	for i, v := range a {
		if v != i+1 {
			return false
		}
	}
	return true
}

func reverseSeg(a []int, l, r int) {
	for l < r {
		a[l], a[r] = a[r], a[l]
		l++
		r--
	}
}

func getStrips(a []int) []Pair {
	n := len(a)
	res := make([]Pair, 0, 8)
	i := 0
	for i < n {
		if i == n-1 {
			res = append(res, Pair{i, i})
			break
		}
		d := a[i+1] - a[i]
		if d != 1 && d != -1 {
			res = append(res, Pair{i, i})
			i++
			continue
		}
		j := i + 1
		for j < n-1 && a[j+1]-a[j] == d {
			j++
		}
		res = append(res, Pair{i, j})
		i = j + 1
	}
	return res
}

func countStrips(a []int) int {
	n := len(a)
	cnt := 0
	i := 0
	for i < n {
		cnt++
		if i == n-1 {
			break
		}
		d := a[i+1] - a[i]
		if d != 1 && d != -1 {
			i++
			continue
		}
		j := i + 1
		for j < n-1 && a[j+1]-a[j] == d {
			j++
		}
		i = j + 1
	}
	return cnt
}

func genCandidates(a []int, strips []Pair) []Cand {
	n := len(a)
	pos := make([]int, n+1)
	for i, v := range a {
		pos[v] = i
	}

	cands := make([]Cand, 0, 128)
	seen := make(map[int]bool, 128)

	add := func(l, r int) {
		if l < 0 || r >= n || l >= r {
			return
		}
		key := l*n + r
		if seen[key] {
			return
		}
		seen[key] = true
		cands = append(cands, Cand{l: l, r: r})
	}

	for i := 0; i < len(strips); i++ {
		for j := i; j < len(strips); j++ {
			add(strips[i].l, strips[j].r)
		}
	}

	for _, seg := range strips {
		l, r := seg.l, seg.r

		if l > 0 {
			x := a[l-1]
			if x > 1 {
				add(l, pos[x-1])
			}
			if x < n {
				add(l, pos[x+1])
			}
		}

		x := a[l]
		if x > 1 {
			add(l, pos[x-1]-1)
		}
		if x < n {
			add(l, pos[x+1]-1)
		}

		if r < n-1 {
			x = a[r+1]
			if x > 1 {
				add(pos[x-1], r)
			}
			if x < n {
				add(pos[x+1], r)
			}
		}

		x = a[r]
		if x > 1 {
			add(pos[x-1]+1, r)
		}
		if x < n {
			add(pos[x+1]+1, r)
		}
	}

	first := -1
	for i, v := range a {
		if v != i+1 {
			first = i
			break
		}
	}
	if first != -1 {
		add(first, pos[first+1])
		last := -1
		for i := n - 1; i >= 0; i-- {
			if a[i] != i+1 {
				last = i
				break
			}
		}
		if last != -1 {
			add(pos[last+1], last)
			add(first, last)
		}
	}

	return cands
}

func dfs(a []int, depth int, lastL, lastR int) bool {
	if isSorted(a) {
		return true
	}
	if depth == 0 {
		return false
	}

	strips := getStrips(a)
	cands := genCandidates(a, strips)

	for i := range cands {
		reverseSeg(a, cands[i].l, cands[i].r)
		if isSorted(a) {
			cands[i].s = 0
		} else {
			cands[i].s = countStrips(a)
		}
		reverseSeg(a, cands[i].l, cands[i].r)
	}

	sort.Slice(cands, func(i, j int) bool {
		if cands[i].s != cands[j].s {
			return cands[i].s < cands[j].s
		}
		if cands[i].l != cands[j].l {
			return cands[i].l < cands[j].l
		}
		return cands[i].r < cands[j].r
	})

	for _, c := range cands {
		if c.l == lastL && c.r == lastR {
			continue
		}
		reverseSeg(a, c.l, c.r)
		path = append(path, Pair{c.l + 1, c.r + 1})
		if dfs(a, depth-1, c.l, c.r) {
			reverseSeg(a, c.l, c.r)
			return true
		}
		path = path[:len(path)-1]
		reverseSeg(a, c.l, c.r)
	}

	return false
}

func main() {
	in := bufio.NewReaderSize(os.Stdin, 1<<20)
	out := bufio.NewWriterSize(os.Stdout, 1<<20)
	defer out.Flush()

	var n int
	fmt.Fscan(in, &n)
	a := make([]int, n)
	for i := 0; i < n; i++ {
		fmt.Fscan(in, &a[i])
	}

	for d := 0; d <= 3; d++ {
		path = path[:0]
		if dfs(a, d, -1, -1) {
			fmt.Fprintln(out, len(path))
			for i := len(path) - 1; i >= 0; i-- {
				fmt.Fprintln(out, path[i].l, path[i].r)
			}
			return
		}
	}

	fmt.Fprintln(out, 0)
}