본문 바로가기

알고리즘/그래프 탐색(BFS)

백준 2178 미로 탐색 - Swift

https://www.acmicpc.net/problem/status/2178/74/2

 

2178번 맞힌 사람 (Swift) - 2 페이지

모든 언어C++JavaPythonCC++17Java 8Python 3C11PyPy3C99C++98C++11C++14Java 8 (OpenJDK)Java 11C++20Python 2PyPy2RubyKotlin (JVM)Kotlin (Native)CythonSwiftTextC#node.jsGoGo (gccgo)Java 15DD (LDC)F# (Mono)PHPRust 2015Rust 2018PascalScalaLuaPerlRakuRuby 1.8R

www.acmicpc.net

문제

N×M크기의 배열로 표현되는 미로가 있다.

1 0 1 1 1 1
1 0 1 0 1 0
1 0 1 0 1 1
1 1 1 0 1 1

미로에서 1은 이동할 수 있는 칸을 나타내고, 0은 이동할 수 없는 칸을 나타낸다. 이러한 미로가 주어졌을 때, (1, 1)에서 출발하여 (N, M)의 위치로 이동할 때 지나야 하는 최소의 칸 수를 구하는 프로그램을 작성하시오. 한 칸에서 다른 칸으로 이동할 때, 서로 인접한 칸으로만 이동할 수 있다.

위의 예에서는 15칸을 지나야 (N, M)의 위치로 이동할 수 있다. 칸을 셀 때에는 시작 위치와 도착 위치도 포함한다.

입력

첫째 줄에 두 정수 N, M(2 ≤ N, M ≤ 100)이 주어진다. 다음 N개의 줄에는 M개의 정수로 미로가 주어진다. 각각의 수들은 붙어서 입력으로 주어진다.

출력

첫째 줄에 지나야 하는 최소의 칸 수를 출력한다. 항상 도착위치로 이동할 수 있는 경우만 입력으로 주어진다.

예제 입력 1 복사

4 6
101111
101010
101011
111011

예제 출력 1 복사

15

 

풀이 방법

2차원 배열에서 1의 길을 지나면서 전의 길에 +1 씩 해주어서 거리를 구합니다.

문제는 길을 DFS로 지날 것이냐 BFS로 지날 것이냐 입니다.

그런데 미로 탐색 같은 최단 거리 구하는 문제는 BFS로 풀어야 합니다. 왜냐하면 최단 거리를 보장해 주기 때문입니다.

위와 같은 예제에서 DFS를 한다고 생각했을 때 핑크색 길 먼저 간다고 생각하면 거리가 11로 도착하게 됩니다. 그러나 이 길이 최단 거리 인지는 모릅니다. 따라서 다른 길도 모두 갔다가 그중 최솟값을 택해야 합니다.

그러나 BFS를 한다면, 핑크색길, 초록색길 모두 한 칸씩 가봅니다. 그러다가 초록색 거리 9, 핑크색 거리 9에서 초록색은 도착지점에 오게 됩니다. 그러므로 핑크색길은 더 안 가도 되고 그 상태로 반복문이 끝나게 됩니다.

 

코드

let NM = readLine()!.split(separator: " ").map{ Int($0)! }
var map = Array(repeating: Array(repeating: 0, count: NM[1]), count: NM[0])

for i in 0..<NM[0] {
    let info = readLine()!
    let infoArr = info.map{ Int(String($0))! }
    
    for j in 0..<infoArr.count {
        map[i][j] = infoArr[j]
    }
}

func bfs(start: (x: Int, y: Int)) {
    var visited = Array(repeating: Array(repeating: false, count: NM[1]), count: NM[0])
    var queue = [start]
    var index = 0
    var dx = [0, 0, 1, -1] // 위, 아래, 오른쪽, 왼쪽
    var dy = [-1, 1, 0, 0]
    var answer = Array(repeating: Array(repeating: 0, count: NM[1]), count: NM[0])
    answer[start.x][start.y] = 1
    
    while queue.count > index {
        let node = queue[index]

            for i in 0..<dx.count {
                let nextX = node.x + dx[i]
                let nextY = node.y + dy[i]
            
                if nextX < 0 || nextX >= NM[0] || nextY < 0 || nextY >= NM[1] {
                    continue
                }
                else {
                    if map[nextX][nextY] == 1 && !visited[nextX][nextY] {
                        queue.append((nextX, nextY))
                        visited[nextX][nextY] = true
                        answer[nextX][nextY] += answer[node.x][node.y] + 1
                    }
                }
            }

        index += 1
    }
    
    print(answer.flatMap{ $0 }.last!)
}

bfs(start: (0, 0))
반응형

'알고리즘 > 그래프 탐색(BFS)' 카테고리의 다른 글

프로그래머스_순위 - Swift  (0) 2022.03.30
프로그래머스_가장먼노드  (0) 2022.03.28
백준 7576 토마토 - Swift  (0) 2022.03.02
백준 1697 숨박꼭질 - Swift  (0) 2022.02.25