import java.util.LinkedList import kotlin.math.abs /** * I'm not sure about the correctness of this aproach. It might be to greedy for hitting the requested max flips. * * I try to create a hamilton path through a fully connected graph. Idea is to be greedy from 2 sides. * Add the cheapest path from the front and the end. This guarantees that the longest path is not included in the path * * Verifying this solution is hard. Since even if your answer does not match the sample output, it might still be correct. * It is good that you warn for it, but the question is if this added complexity should be in a problem. */ fun main() { val psalms = readLine()!!.toInt() var costs = readLine()!!.split(" ").map { it.toInt() }.withIndex().map { it.copy(index = it.index + 1) } val seen = mutableSetOf() val path = LinkedList>() val start = costs.minByOrNull { (index, value) -> index + value }!! path.addFirst(start.index to start.value) seen.add(start.index) costs = costs.filter { it.index !in seen } var minStart = costs.minByOrNull { path.first().cost(it) } var minEnd = minStart?.copy() fun updateValues(indexedValue: IndexedValue) { seen.add(indexedValue.index) costs = costs.filter { it.index !in seen } } fun addToStart(indexedValue: IndexedValue) { path.addFirst(indexedValue.index to indexedValue.value) updateValues(indexedValue) if(minStart == minEnd) { // deal with the start case minEnd = costs.minByOrNull { path.last().cost(it) } } minStart = costs.minByOrNull { path.first().cost(it) } } fun addToEnd(indexedValue: IndexedValue) { path.addLast(indexedValue.index to indexedValue.value) updateValues(indexedValue) if(minStart == minEnd) { // deal with the start case minStart = costs.minByOrNull { path.first().cost(it) } } minEnd = costs.minByOrNull { path.last().cost(it) } } while (seen.size < psalms) { val begin = path.first() val end = path.last() val startCost = begin.cost(minStart!!) val endCost = end.cost(minEnd!!) if (startCost < endCost) { addToStart(minStart!!) } else { addToEnd(minEnd!!) } } println(path.joinToString(separator = "\n") { (a, b) -> "$a $b" }) } fun Pair.cost(other: IndexedValue) = abs(first - other.index) + abs(second - other.value)