본문 바로가기

알고리즘/구현

백준 - 뱀(Kotlin)

본 알고리즘 풀이는 Routine Study에서 진행하고 있습니다.

https://github.com/ROUTINE-STUDY/Algorithm

 

저를 포함한 구성원이 대부분 초보이므로, 원하시는분은 언제라도 들어오셔도 좋습니다.

 

GitHub - ROUTINE-STUDY/Algorithm: 초보 알고리즘 스터디 / 누구나 참여 가능

초보 알고리즘 스터디 / 누구나 참여 가능 :runner:. Contribute to ROUTINE-STUDY/Algorithm development by creating an account on GitHub.

github.com

문의는 댓글 바람.

 

문제 출처 :https://www.acmicpc.net/problem/3190

 

[문제 설명]

구현해라

 

[접근 방법]

단순 구현 문제이다. 단, 코드가 복잡하므로 최대한 메서드를 분리해서 짰다.

 

import java.io.BufferedReader
import java.io.InputStreamReader
import java.util.LinkedList

private val dy = intArrayOf(-1, 0, 1, 0)
private val dx = intArrayOf(0, 1, 0, -1)
private var currentDirectionIdx = 1
private val currentPointOfSnakeHead = intArrayOf(1, 1)
private val directionPerTime = LinkedList<Pair<Int, Char>>()
private lateinit var appleExist: Array<BooleanArray>

fun main() {
    val br = BufferedReader(InputStreamReader(System.`in`))
    val n = br.readLine().toInt()
    if (n == 1) {
        println(0)
        return
    }

    appleExist = Array(n + 1) { BooleanArray(n + 1)}
    val cntOfApple = br.readLine().toInt()

    repeat(cntOfApple) {
        val (appleRow, appleCol) = br.readLine().split(" ").map { it.toInt() }
        appleExist[appleRow][appleCol] = true
    }


    val cntOfDirectionInput = br.readLine().toInt()
    repeat(cntOfDirectionInput) {
        val (time, direction) = br.readLine().split(" ")
        directionPerTime.offer(time.toInt() to direction[0])
    }

    println(getGameFinishTime(n) + 1)
}

private fun getGameFinishTime(size: Int): Int {
    var currentTime = 0
    var bodyPosition = LinkedList<Pair<Int, Int>>()
    bodyPosition.offer(1 to 1)

    while (true) {
        if (isDirectionChangeTime(currentTime)) {
            val changeDirection = directionPerTime.poll().second
            changeCurrentDirection(changeDirection)
        }

        val nextHeadPoint = intArrayOf(currentPointOfSnakeHead[0] + dy[currentDirectionIdx], currentPointOfSnakeHead[1] + dx[currentDirectionIdx])
        if (isGameEnd(nextHeadPoint[0], nextHeadPoint[1], size, bodyPosition)) {
            return currentTime
        }

        if (!appleExist[nextHeadPoint[0]][nextHeadPoint[1]]) {
            bodyPosition.poll()
        }
        appleExist[nextHeadPoint[0]][nextHeadPoint[1]] = false

        bodyPosition.offer(nextHeadPoint[0] to nextHeadPoint[1])
        currentPointOfSnakeHead[0] = nextHeadPoint[0]
        currentPointOfSnakeHead[1] = nextHeadPoint[1]

        currentTime++
    }

    return -1
}

private fun isDirectionChangeTime(currentTime: Int): Boolean {
    if (directionPerTime.size == 0) {
        return false
    }

    val changeTimeAndDirection = directionPerTime.peek()
    if (changeTimeAndDirection.first == currentTime) {
        return true
    }

    return false
}

private fun isGameEnd(r: Int, c: Int, mapSize: Int, bodyPosition: LinkedList<Pair<Int,Int>>): Boolean {
    if (r !in 1..mapSize || c !in 1..mapSize) {
        return true
    }
    bodyPosition.forEach {
        if (r == it.first && c == it.second) {
            return true
        }
    }
    return false
}

private fun changeCurrentDirection(side: Char) {
    when (side) {
        'L' -> {
            currentDirectionIdx -= 1
        }
        'D' -> {
            currentDirectionIdx += 1
        }
    }

    if (currentDirectionIdx < 0) {
        currentDirectionIdx = 3
    } else if (currentDirectionIdx == 4) {
        currentDirectionIdx = 0
    }
}

 

[느낀 점]

사실 조건 딱 하나를 체크 안해서 한 번에 통과하지 못한 문제다.

먹은 사과를 처리해줬어야 하는데 그러지 못했다.

이런 구현류 문제들이 늘 그렇 듯이 하나라도 실수하면 엇나가느라 스트레스가 상당한 문제다.

그래도 바로 고쳐서 풀었으니 거기에 의의를 두자.

 

728x90
반응형