Programming/Algorithm & Data Structure
[Swift] 백준 미로 보수 30689
guswlsdk
2025. 2. 11. 19:43
반응형
https://www.acmicpc.net/problem/30689
1. 문제이해
- 세로 N, 가로 M, N * M 크기의 미로
- 화살표를 따라 미로 범위 밖으로 나갈 수 있으면 탈출 성공
- 사이클의 경우 점프대를 설치하여 탈출할 수 있다.
- 미로의 어느 칸에서 시작하더라도 탈출할 수 있도록 만들자. 단, 최소한의 비용을 사용해 점프대를 설치해야 한다. 필요한 최소한의 비용을 구하자.
2. 접근방법
- dfs로 경로 탐색
- 이동 시 경로를 스택에 저장
- 이동 할 칸이 방문 했던 칸이라면 사이클 의심
- 스택에 저장된 경로대로 거꾸로 탐색하여 사이클 의심되는 칸을 도달할 경우 사이클, 최소 설치 비용 구하기
func solution(){
let input = readLine()!.split(separator: " ").map{Int(String($0))!}
let N = input[0]
let M = input[1]
var map = [[String]]() // 미로
var cost = [[Int]]() // 점프대 설치 비용
var visited = Array(repeating: Array(repeating: false, count: M), count: N)
var stack = [(Int, Int)]() //
var result = 0
for _ in 0..<N{
map.append(readLine()!.map{String($0)})
}
for _ in 0..<N{
cost.append(readLine()!.split(separator: " ").map{Int(String($0))!})
}
func dfs(x: Int, y: Int){
let arrow = map[x][y]
var nextX = x
var nextY = y
if arrow == "L"{
nextY -= 1
}else if arrow == "R"{
nextY += 1
}else if arrow == "U"{
nextX -= 1
}else{ // D
nextX += 1
}
if nextX >= 0, nextX < N, nextY >= 0, nextY < M {
if visited[nextX][nextY] == false{ // 다음 칸이 방문하지 않은 칸이라면
visited[x][y] = true
stack.append((nextX, nextY)) // 스택에 경로 추가
dfs(x: nextX, y: nextY)
stack.removeLast()
}else{
// 다음 칸이 방문했던 칸이라면 사이클이 발생했다고 볼 수 있는데...
// 스택에 저장된 경로대로 거꾸로 탐색, 최소 설치 비용 구하기
// 탐색 중 사이클 발생 지점(현재 위치에서 다음 칸)에 도달한다면
var minCost = Int.max
for point in stack.reversed(){
minCost = min(minCost, cost[point.0][point.1])
if point.0 == nextX, point.1 == nextY{
result += minCost
break
}
}
}
}
}
for i in 0..<N{
for j in 0..<M{
if !visited[i][j]{
stack.append((i,j))
dfs(x: i, y: j)
stack.removeLast()
}
}
}
print(result)
}
solution()
반응형