본문 바로가기
코딩테스트

[이것이 코딩테스트다] Chapter 05 DFS/BFS - 미로 탈출

by 박매트 2024. 3. 23.

N, M 직사각형 형태의 미로에 갇혀 있다. 미로에는 여러 마리의 괴물이 있어 이를 피해 탈출해야한다.

 

동빈이의 위치는 (1,1)이고 미로의 출구는 (N,M) 의 위치하며 한 번에 한 칸씩 이동할 수 있따.

괴물이 있는 부분은 0, 괴물이 없는 부분은 1로 표시되어 있따. 동빈이가 탈출하기 위한 최소 칸의 개수를 구하시오. 칸을 셀 때는 시작칸과 마지막 칸을 모두 포함해서 계산한다.

 

Sol)

BFS를 이용했을 때 매우 효과적으로 해결할 수 있다. BFS는 시작 시점에서 가까운 노드부터 차례대로 그래프의 모든 노드를 탐색하기 때문이다. 그러므로 (1,1) 지점에 서부터 BFS를 수행하여 모든 노드의 값을 거리 정보로 넣으면 된다.

 

특정한 노드를 방문하면 그 이전 노드의 거리에 1을 더한 값을 리스트에 넣는다. 

 

from collections import deque

# N, M을 공백으로 구분하여 입력받기
n, m = map(int, input().split())
# 2차원 리스트의 맵 정보 입력받기
graph = []
for i in range(n):
    graph.append(list(map(int, input())))

# 이동할 네 방향 정의(상, 하, 좌, 우)
dx = [-1,1,0,0]
dy = [0,0,-1,1]

# BFS 소스코드 구현
def bfs(x, y):
    # 큐(QUeue) 구현을 위해 deque 라이브러리 사용
    queue = deque()
    queue.append((x,y))
    # 큐가 빌 때까지 반복
    while deque:
        x, y = queue.popleft()
        # 현재 위치에서 네 방향으로의 위치 확인
        for i in range(4):
            nx = x+dx[i]
            ny= y+dy[i]
            # 미로 찾기 공간을 벗어난 경우 무시
            if nx < 0 or ny < 0 or nx>=n or ny>= m:
                continue
            # 벽이 ㄴ경우 무시
            if graph[x][y] == 0:
                continue
            # 해당 노드를 처음 방문하는 경우에만 최단 거리 기록
            if graph[nx][ny] == 1:
                graph[nx][ny]= graph[x][y] + 1
                queue.append((nx,ny))
        # 가장 오른쪽 아래까지의 최단 거리 반환
    return graph[n-1][m-1]

# BFS를 수행한 결과 출력
print(bfs(0,0))

 

첫 시작 위치를 큐에다 넣어놓고 

위치를 기준으로 네 방향으로의 위치를 확인해서 처음 방문하는 경우 값을 거리 값을 더해나가고, 큐에 넣는다.

들어온 값 순서대로 또 그 값에 따른 네 방향으로의 위치를 확인하고 또 거리 값을 더해나감..

 

길대로 확인해나가다보면, 가장 오른쪽 아래까지의 최단 거리를 반환할 수 있다...