728x90
https://www.acmicpc.net/problem/1261
1261번: 알고스팟
첫째 줄에 미로의 크기를 나타내는 가로 크기 M, 세로 크기 N (1 ≤ N, M ≤ 100)이 주어진다. 다음 N개의 줄에는 미로의 상태를 나타내는 숫자 0과 1이 주어진다. 0은 빈 방을 의미하고, 1은 벽을 의미
www.acmicpc.net
문제 풀이
1. (1, 1) -> (M, N) 까지 가는 최단 거리를 구하는 BFS 탐색을 이용한다.
2. 탐색 시 벽일 경우는 깨고 지나가야 하는데 최소한으로 벽을 깨야 하므로 벽이 있을 때와 없을 때의 경로 이동 시 가중치가 다르므로 다익스트라를 이용한다.
3. Wall Class 를 선언하고 우선 순위 큐에 저장한다. 벽을 깬 횟수를 기준으로 오름 차순 정렬한다.
4. 벽을 깬 횟수를 저장하는 dp 2차원 배열을 선언한다.
코드
import java.io.*
import java.util.*
fun main(args: Array<String>) {
val br = BufferedReader(InputStreamReader(System.`in`))
val (M, N) = br.readLine().split(" ").map { it.toInt() }
val maze = Array(N + 1) { IntArray(M + 1) { 0 } }
repeat(N) { index1 ->
val input = br.readLine().toCharArray()
input.forEachIndexed { index2, c ->
maze[index1 + 1][index2 + 1] = c.digitToInt()
}
}
dijkstra(N, M, maze)
println()
}
private fun dijkstra(N: Int, M: Int, maze: Array<IntArray>) {
val queue = PriorityQueue<Wall>()
queue.add(Wall(1, 1, 0))
// 이미 방문한 영역인 지 확인하는 배열
val visit = Array(N + 1) { BooleanArray(M + 1) { false } }
visit[1][1] = true
// 벽을 깬 횟수를 저장하는 배열
val dp = Array(N + 1) { IntArray(M + 1) { Int.MAX_VALUE } }
dp[1][1] = 0
while (queue.isNotEmpty()) {
val (curX, curY, curBroken) = queue.poll()!!
val changeX = intArrayOf(1, 0, -1, 0)
val changeY = intArrayOf(0, 1, 0, -1)
//println("(curX : $curX, curY : $curY, curBroken : $curBroken) ${dp[curX][curY]}")
if (curX == N && curY == M) {
println(dp[curX][curY])
break
}
for (i in 0..3) {
val newX = curX + changeX[i]
val newY = curY + changeY[i]
// 범위 밖
if ((newX < 1 || newX > N) || (newY < 1 || newY > M)) continue
// 이미 방문한 영역
if (visit[newX][newY]) continue
//println("(newX : $newX, newY : $newY) ${dp[newX][newY]}")
visit[newX][newY] = true
if (dp[newX][newY] > curBroken + dp[curX][curY]) {
if (maze[newX][newY] == 1) {
dp[newX][newY] = dp[curX][curY] + 1
} else {
dp[newX][newY] = dp[curX][curY]
}
}
queue.add(Wall(newX, newY, dp[newX][newY]))
}
}
}
// 벽을 깰지 말지에 따라 가중치가 다르므로 벽을 부순 횟수를 기준으로 정렬하여 우선순위 큐에 저장되도록 한다.
private data class Wall(val x: Int, val y: Int, val broken: Int) : Comparable<Wall> {
override fun compareTo(other: Wall): Int {
return broken - other.broken
}
}
728x90
'알고리즘(w.KOTLIN) > 그래프(bfs, dfs, 다익스트라)' 카테고리의 다른 글
[백준][코틀린][1167] 트리의 지름 (0) | 2023.02.27 |
---|---|
[백준][코틀린][11725] 트리의 부모 찾기 (0) | 2023.02.27 |
[백준][코틀린][14226] 이모티콘 (0) | 2023.02.20 |
[백준][코틀린][13549] 숨바꼭질3 (0) | 2023.02.20 |
[백준][코틀린][13913] 숨바꼭질4 (0) | 2023.02.20 |