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