[백준] 달팽이2 (1952)(kotlin)

문제 설명

백준 1952번 문제 링크

입력 및 출력

» 입력

첫째 줄에 M과 N이 빈 칸을 사이에 두고 주어진다. (2≤M, N≤100)

» 출력

첫째 줄에 표의 모든 칸이 채워질 때까지 선이 꺾어지는 횟수를 출력한다.

예제 입출력(테스트케이스)

입력 출력
5 3 5

문제 풀이1

import java.io.BufferedReader
import java.io.InputStreamReader

val dx = intArrayOf(1, 0, -1, 0)
val dy = intArrayOf(0, 1, 0, -1)
//달팽이 이동 방향 반복 -> 우, 하, 좌, 상

fun main(args: Array<String>) = with(BufferedReader(InputStreamReader(System.`in`))) {
    val (y: Int, x: Int) = readLine()
        .split(" ")
        .map { it.toInt() }

    var snail = Array(y) { BooleanArray(x) { false } }
    var count = 0
    var vector = 0

    var nextX = 0
    var nextY = 0
    snail[nextY][nextX] = true

    while (true) {
        // 기존 진행방향 저장
        val oldVector = vector

        // 외곽을 순환할때
        if (dx[vector] + nextX !in 0 until x || dy[vector] + nextY !in 0 until y) {
            vector = if (vector == 3) 0 else vector + 1
        } else { // 외곽을 다 순환하고 내곽을 순환하기 시작할 때, 진행방향 바꿈
            if (!snail[nextY][nextX]) {
                vector = if (vector == 3) 0 else vector + 1
            }
        }

        // 내곽을 순환할때
        if (snail[dy[vector] + nextY][dx[vector] + nextX]) {
            vector = if (vector == 3) 0 else vector + 1

            // "달팽이 2" 문제의 경우 순환할 곳이 남았다면, 다음이 무조건 true임을 보장
            // 다음이 존재하지 않는다면(탐색하지 않은 곳 "false"), 모든 곳을 순회한 것으로 간주. break
            if (snail[dy[vector] + nextY][dx[vector] + nextX]) {
                println(count)
                break
            }
        }

        // 진행방향이 바뀌었을 경우, 카운트++
        count = if (vector != oldVector) count + 1 else count

        nextX += dx[vector]
        nextY += dy[vector]
        snail[nextY][nextX] = true
    }
}