Computer Science/알고리즘

백준 2178번 미로탐색 (너비 우선 탐색 BFS)

조용우 2021. 6. 11. 00:00

문제

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개의 정수로 미로가 주어진다. 각각의 수들은 붙어서 입력으로 주어진다.

출력

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

예제 입력

4 6

101111

101010

101011

111011

예제 출력

15

 


풀이

BFS를 공부하면서 파이썬으로 구현했던 BFS 코드를 이용했다. 입력을 딕셔너리 형식으로, 해당 칸의 좌표를 키값으로 하고 밸류 값으로는 리스트에 시작점으로부터의 거리와 해당 칸의 부모 노드를 설정했다.

 

입력받을 때 모든 칸을 확인하면서 해당 칸의 값이 1이면, 인접한 모든 1인 칸과 연결되도록 딕셔너리를 구현해서 그래프 형식으로 저장했다. 찾고자 하는 좌표(N, M)의 거리를 알면 되기에, 키 "N M"의 밸류 값인 거리를 출력하면 시작점으로부터 N M까지의 거리가 나온다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
def bfs(graph, s):
    
    visited = dict()
    withOutParent = list()
    parent = dict()
    queue = list()
    
    visited[s] = [1"NIL"]
    queue.extend(graph[s])
    for i in range(0len(graph[s])):
        parent[ graph[s][i] ] = s
    while queue:
        vertex = queue.pop(0)
        if vertex not in visited:
            visited[vertex] = [visited[parent[vertex]][0+ 1, parent[vertex]] #[거리, 부모]
            
            withOutParent = graph[vertex]
            withOutParent.remove(parent[vertex])
            
            for v in withOutParent:
                if v in queue:
                    withOutParent.remove(v)
            queue.extend(withOutParent)
            
            for i in range(0len(withOutParent)):
                parent[withOutParent[i]] = vertex
            
    return visited
 
data = dict()
 
N, M = map(int, input().split())
maze = [[0]*for i in range(N)]
 
for i in range(0, N):
    temp = list(map(int, input()))
    for j in range(0, M):
        maze[i][j] = temp.pop(0)
        data[str(i) + str(j)] = []
 
for i in range(0, N):
    for j in range(0, M):
        if 0 <= i+1 < N:
            if maze[i][j] == 1 and maze[i + 1][j] == 1:
                data[str(i) + str(j)].append(str(i+1+ str(j))
                data[str(i+1+ str(j)].append(str(i) + str(j))
        if 0 <= j+1 < M:
            if maze[i][j] == 1 and maze[i][j+1== 1:
                data[str(i) + str(j)].append(str(i) + str(j+1))
                data[str(i) + str(j+1)].append(str(i) + str(j))
 
 
answer = bfs(data, "00")
print(answer[str(N-1)+str(M-1)][0])
cs