백준 [2638] kotlin

[문제]

https://www.acmicpc.net/problem/2638

 

2638번: 치즈

첫째 줄에는 모눈종이의 크기를 나타내는 두 개의 정수 N, M (5 ≤ N, M ≤ 100)이 주어진다. 그 다음 N개의 줄에는 모눈종이 위의 격자에 치즈가 있는 부분은 1로 표시되고, 치즈가 없는 부분은 0으로

www.acmicpc.net

[풀이]

이 문제의 핵심은 다음과 같다.

  1. 바깥과 닿아있는 부분만 외부 공기이다. 치즈로 둘러쌓인 내부의 공기는 외부 공기가 아니다.
  2. 외부 공기와 최소 2면이 닿는 치즈는 한 시간 후에 녹는다.

BFS 과정은 다음과 같다.

이동할 배열을 저장해두는 deque를 생성한다.

가장 먼저, 방문한 곳을 기록해두는 visit이라는 배열을 생성한다. 방문한 곳은 -1로 저장을 하고, 치즈인곳은 접한 횟수를 체크해야하기 때문에 치즈인 곳을 찾을 때마다 기존 값에 +1을 해준다.

 

외각 공기로 이동을 하면서, 상하좌우를 체크를 한다.

 

이 때 두 가지 경우로 나뉜다.

1. 치즈인 경우

치즈인 경우에는 visit배열에 +1을 해준다.

2. 공기인 경우

이미 방문한 공기인지 체크하기 위해 visit가 -1이 아니면, 방문을 한 적이 없는 경우이므로 -1로 저장을 하고 deque에 추가를 한다.

 

BFS가 끝나면, visit 배열을 탐색하면서 2이상인 위치의 cheese를 0으로 바꾸어 준다.

 

위의 BFS과정을 모든 치즈가 녹을때까지 반복한다.

 

[코드]

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

var N = 0
var M = 0
lateinit var cheese : ArrayList<ArrayList<Int>>
var dx = listOf(0,0,1,-1)
var dy = listOf(1,-1,0,0)
fun main()
{
    var br = BufferedReader(InputStreamReader(System.`in`))
    var bw = BufferedWriter(OutputStreamWriter(System.out))

    val tmp = br.readLine().split(" ").map { it.toInt() }
    N = tmp[0]
    M = tmp[1]

    cheese = arrayListOf()
    repeat(N) {cheese.add(ArrayList(br.readLine().split(" ").map { it.toInt() })) }

    var ans = 0
    /* 외각 찾기 */
    val k = findZero()
    while (true)
    {
        if(bfs(k.first,k.second)) ans++
        else break
    }
    bw.write(ans.toString())
    bw.flush()
    bw.close()
}
fun findZero() : Pair<Int, Int>
{
    for (i in 0 until N)
    {
        if(cheese[i][0]==1) return Pair(i,0)
        if(cheese[i][M-1]==1) return Pair(i,M-i)
    }
    for (i in 0 until M)
    {
        if(cheese[0][i]==1) return Pair(0,i)
        if(cheese[N-1][i]==1) return Pair(N-1,i)
    }
    return Pair(0,0)
}

fun bfs(x : Int, y : Int) : Boolean
{
    var q : Deque<Pair<Int,Int>> = LinkedList()
    var visited = Array(N, {IntArray(M,{0})})
    q.add(Pair(x,y))
    while (q.isNotEmpty())
    {
        val pq = q.removeFirst()
        repeat(4)
        {
            i ->
            var nx = pq.first + dx[i]
            var ny = pq.second + dy[i]
            if(nx in 0 until N && ny in 0 until M)
            {
                /* 치즈가 있는 곳인 경우 */
                if(cheese[nx][ny] == 1)
                {
                    visited[nx][ny]++
                }
                /* 치즈가 없는 곳인 경우 */
                else
                {
                    /* 방문한 치즈인지 체크 */
                    if(visited[nx][ny] != -1) {
                        visited[nx][ny] = -1
                        q.add(Pair(nx,ny))
                    }
                }
            }
        }
    }
    var check = false
    for(i in 0 until N)
    {
        for(j in 0 until M)
        {
            if(visited[i][j] >= 2)
            {
                cheese[i][j] = 0
                check = true
            }
        }
    }
    return check
}

'백준 > bfs dfs' 카테고리의 다른 글

백준 [4179] kotlin  (1) 2023.01.18
백준 [1167] kotlin  (0) 2023.01.16
백준 [1967] kotlin  (0) 2023.01.14
백준 [16234] kotlin  (1) 2023.01.10
백준 [4485] kotlin  (0) 2023.01.06