링크 : https://www.acmicpc.net/problem/2636

 

2636번: 치즈

아래 <그림 1>과 같이 정사각형 칸들로 이루어진 사각형 모양의 판이 있고, 그 위에 얇은 치즈(회색으로 표시된 부분)가 놓여 있다. 판의 가장자리(<그림 1>에서 네모 칸에 X친 부분)에는 치즈가 놓

www.acmicpc.net

치즈 내부 공간과 외부 공간을 구분하기 위해서 

매번 치즈를 녹이기 전에 미리 bfs로 외부공간을 "2"로 표시해두고 "2"인 공간과 인접해있는 치즈만

녹이는 방식으로 풀이


소스코드 (Implement, BFS)

import java.io.BufferedReader
import java.io.FileInputStream
import java.io.InputStreamReader
import java.util.*

private var R = 0 //세로 (양의 정수, 최대 100)
private var C = 0 //가로 (양의 정수, 최대 100)
private var time = 0
private var lastCheeseCount = 0
private var cheeseCountList = mutableListOf<Int>()
private val MY = arrayOf(0, -1, 0, 1) //우하좌상
private val MX = arrayOf(1, 0, -1, 0) //우하좌상
private lateinit var cheeseMap: Array<Array<String>>

private fun main() {
    val br = BufferedReader(InputStreamReader(System.`in`))
    br.readLine().split(" ").map { it.toInt() }.apply {
        R = this[0]
        C = this[1]
    }
    cheeseMap = Array(R) { arrayOf() }
    repeat(R) {
        cheeseMap[it] = br.readLine().split(" ").toTypedArray()
    }
    while (true) {
        checkOutSpace()
        meltCheese()
        if (lastCheeseCount == 0) break
        time++
        cheeseCountList.add(lastCheeseCount)
        lastCheeseCount = 0
    }
    println(time)
    println(cheeseCountList.last())
}

//안쪽 공간과 바깥쪽 공간을 구분해야함
private fun checkOutSpace() {
    val Q: Queue<Point> = LinkedList()
    val isVisited = Array(R) { BooleanArray(C) { false } }
    Q.add(Point(0, 0))
    while (Q.isNotEmpty()) {
        val point = Q.poll()
        cheeseMap[point.y][point.x] = "2"

        for (i in 0 until 4) {
            val checkRow = point.y + MY[i]
            val checkCol = point.x + MX[i]
            if (isInMap(checkRow, checkCol) &&
                (cheeseMap[checkRow][checkCol] != "1") &&
                !isVisited[checkRow][checkCol]
            ) {
                isVisited[checkRow][checkCol] = true
                Q.add(Point(checkRow, checkCol))
            }
        }
    }
}

private fun meltCheese() {
    for (r in 0 until R) {
        for (c in 0 until C) {
            if (cheeseMap[r][c] != "1") continue

            lastCheeseCount++
            //치즈 칸 주변 탐색
            for (i in 0 until 4) {
                val checkRow = r + MY[i]
                val checkCol = c + MX[i]
                //외각을 맞댄 치즈칸이라면 녹임
                if (isInMap(checkRow, checkCol) && cheeseMap[checkRow][checkCol] == "2") {
                    cheeseMap[r][c] = "0"
                    break
                }
            }
        }
    }
}

private fun isInMap(y: Int, x: Int): Boolean =
    (y in 0 until R) && (x in 0 until C)

private data class Point(
    val y: Int,
    val x: Int
)

'Algorithm_Kotlin' 카테고리의 다른 글

[Kotlin] BOJ16234 인구 이동  (0) 2023.04.10
[Kotlin] BOJ2573 빙산  (0) 2023.04.06
[Kotlin] BOJ2116 주사위 쌓기  (0) 2023.04.04
[Kotlin] BOJ1966 프린터 큐  (1) 2023.03.10
[Kotlin] BOJ1913 달팽이  (0) 2023.03.09