Uknow's Lab.
article thumbnail

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

 

16954번: 움직이는 미로 탈출

욱제는 학교 숙제로 크기가 8×8인 체스판에서 탈출하는 게임을 만들었다. 체스판의 모든 칸은 빈 칸 또는 벽 중 하나이다. 욱제의 캐릭터는 가장 왼쪽 아랫 칸에 있고, 이 캐릭터는 가장 오른쪽

www.acmicpc.net

 

난이도 : 골드 3
태그 : 그래프 이론, 그래프 탐색, 너비 우선 탐색

 

 

설명

BFS를 사용한 4방향 델타 탐색 문제입니다

일반 문제와 다른 부분은, 미로가 1초마다 내려온다는 점이죠.

때문에 한 회차마다 이동을 하며 이동이 모두 끝난 뒤 모든 칸을 1만큼 내리는 과정을 반복합니다.

 

 

상하좌우 + 대각선 8방향 탐색 + 제자리

val dx = intArrayOf(-1, -1, -1, 0, 0, 1, 1, 1, 0)
val dy = intArrayOf(-1, 0, 1, -1, 1, -1, 0, 1, 0)

 

상하좌우와 대가선 8방향에 대해 dx, dy를 지정하고,

제자리에 가만히 있기 역시 가능하기 때문에 마지막에 (0,0)도 추가해줬습니다.

 

 

 

한 회차마다 BFS를 돌리기

한 회차마다 이동을 하는 방법은 큐에 저장된 원소의 개수만큼 BFS를 돌리는 것인데요.

while (q.isNotEmpty()) {
    val visited = Array(n) { BooleanArray(n) }

    for (i in 0..<q.size) {
        val target = q.poll()

        // BFS 진행
        for(i in dx.size) {
            (생략)
            q.add(Node(nx, ny))
        }
    }
    
    (벽 내리기)
}

 

큐의 size 씩 BFS를 수행하고,

또 다시 큐에 원소를 넣음으로써 한 회차마다 BFS를 진행할 수 있습니다.

 

 

 

벽 내리기

fun wallDown(map: Array<CharArray>) {
    for (i in map.size - 1 downTo 1) {
        for (j in map[i].indices) {
            map[i][j] = map[i - 1][j]
        }
    }
    map[0] = CharArray(map[0].size) { '.' }
}

 

벽 내리기의 경우, 그냥 for문을 사용하여 바로 윗 칸의 원소를 가져왔습니다.

가장 윗 칸의 경우 '.'으로 지정해줬습니다.

 

 

 

소스코드

import java.util.*

data class Node(val x: Int, val y: Int)

fun main() = with(System.`in`.bufferedReader()) {
    val n = 8
    val map = Array(n) { readLine().toCharArray() }
    val dx = intArrayOf(-1, -1, -1, 0, 0, 1, 1, 1, 0)
    val dy = intArrayOf(-1, 0, 1, -1, 1, -1, 0, 1, 0)

    val q = LinkedList<Node>() as Queue<Node>
    q.add(Node(7, 0))

    while (q.isNotEmpty()) {
        val visited = Array(n) { BooleanArray(n) }

        for (i in 0..<q.size) {
            val target = q.poll()
            if (map[target.x][target.y] == '#') continue
            if (target.x == 0 && target.y == 7) {
                println(1)
                return
            }

            for (j in 0..<9) {
                val nx = target.x + dx[j]
                val ny = target.y + dy[j]
                if (nx !in 0..<n || ny !in 0..<n || map[nx][ny] == '#' || visited[nx][ny]) continue
                visited[nx][ny] = true
                q.add(Node(nx, ny))
            }
        }

        wallDown(map)
    }

    println(0)
}

fun wallDown(map: Array<CharArray>) {
    for (i in map.size - 1 downTo 1) {
        for (j in map[i].indices) {
            map[i][j] = map[i - 1][j]
        }
    }
    map[0] = CharArray(map[0].size) { '.' }
}

 

profile

Uknow's Lab.

@유노 Uknow

인생은 Byte와 Double 사이 Char다. 아무말이나 해봤습니다.