https://coderun.yandex.ru/problem/toy-maze Средняя

Решение

import java.io.BufferedReader
import java.io.BufferedWriter
import java.io.InputStreamReader
import java.io.OutputStreamWriter
import java.util.LinkedList
import java.util.Queue

private var N_MAZE_SIZE = 0
private var M_MAZE_SIZE = 0
private lateinit var mazeGrid: Array<IntArray>

private fun rollBall(startR: Int, startC: Int, dr: Int, dc: Int): Pair<Pair<Int, Int>?, Boolean> {
    var r = startR
    var c = startC
    while (true) {
        val nextR = r + dr
        val nextC = c + dc
        if (nextR < 0 || nextR >= N_MAZE_SIZE || nextC < 0 || nextC >= M_MAZE_SIZE) {
            return Pair(Pair(r, c), false)
        }
        when (mazeGrid[nextR][nextC]) {
            1 -> return Pair(Pair(r, c), false)
            2 -> return Pair(null, true)
            0 -> {
                r = nextR
                c = nextC
            }
        }
    }
}

fun main() {
    val reader = BufferedReader(InputStreamReader(System.`in`))
    val writer = BufferedWriter(OutputStreamWriter(System.out))

    val dimensions = reader.readLine().split(" ")
    N_MAZE_SIZE = dimensions[0].toInt()
    M_MAZE_SIZE = dimensions[1].toInt()

    mazeGrid = Array(N_MAZE_SIZE) { IntArray(M_MAZE_SIZE) }
    for (r in 0 until N_MAZE_SIZE) {
        val rowData = reader.readLine().trim().split(" ")
        for (c in 0 until M_MAZE_SIZE) {
            mazeGrid[r][c] = rowData[c].toInt()
        }
    }

    val dist = Array(N_MAZE_SIZE) { IntArray(M_MAZE_SIZE) { -1 } }
    val q: Queue<Pair<Int, Int>> = LinkedList()
    dist[0][0] = 0
    q.add(Pair(0, 0))

    var minTilts = -1
    val dr = intArrayOf(-1, 1, 0, 0)
    val dc = intArrayOf(0, 0, -1, 1)

    while (q.isNotEmpty()) {
        val (r, c) = q.poll()
        val currentDist = dist[r][c]

        for (i in 0..3) {
            val (endPos, foundHole) = rollBall(r, c, dr[i], dc[i])
            if (foundHole) {
                minTilts = currentDist + 1
                q.clear()
                break
            } else if (endPos != null) {
                val nr = endPos.first
                val nc = endPos.second
                if (dist[nr][nc] == -1) {
                    dist[nr][nc] = currentDist + 1
                    q.add(Pair(nr, nc))
                }
            }
        }
        if (minTilts != -1) break
    }

    writer.write(minTilts.toString())
    writer.newLine()
    reader.close()
    writer.close()
}