[백준] 2178. 미로탐색

주형(Jureamer)·2022년 4월 25일
0

미로탐색

분류

너비 우선 탐색(bfs), 그래프 이론(graphs), 그래프 탐색(graph_traversal)

문제 설명

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

출력

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

문제풀이

미로의 최단거리를 구하는 문제로, BFS(Queue)를 이용하여 문제를 풀었다.

1. (방향 설정 변수 설정) 방향 설정을 위한 변수 선언
2. (방문여부 배열 선언) 방문 여부를 저장하기 위한 chkBoard 선언
3. (while 반복문) queue(dq)에 값이 있다면, 도착하거나, queue에 값이 없을 때까지 반복

  • 하지만 문제는 무조건 도착하는 경우만 주어지므로, 도착할 때만 종료된다

4. (유효값 여부 확인)

  • 4-1 좌표 값이 유효하고,
  • 4-2 벽(0)이 아닌 길(1)이고,
  • 4-3 방문하지 않는 곳인 경우

5. 방문 표시 및 새로운 좌표 값 추가

from collections import deque

#1.  4방향 확인을 위한 변수 설정
dx = (1, 0, -1, 0)
dy = (0, 1, 0, -1)
N, M = map(int, input().split())
board = [input() for _ in range(N)]


def chk_valid_coordinate(y, x):
  return 0 <= x < M and 0 <= y < N

def bfs(y, x, d):
#2. 방문여부 배열 선언 
  chkBoard = [[False] * M for _ in range(N)]
  chkBoard[0][0] = True
  dq = deque()
  dq.append((0, 0, 1))

#3. while 반복문
  while dq:
    y, x, d = dq.popleft()
    if y == N - 1 and x == M - 1:
      print(d)
      
    nd = d + 1
    for i in range(4):
      nx = x + dx[i]
      ny = y + dy[i]
     #4. 좌표 유효성 여부 확인
      if chk_valid_coordinate(ny, nx) and board[ny][nx] == '1' and not chkBoard[ny][nx]:
      
      #5. 방문 표시 및 새로운 좌표 값 append
        chkBoard[ny][nx] = True
        dq.append((ny, nx, nd))

bfs(0, 0, 0)
profile
작게라도 꾸준히 성장하는게 목표입니다.

0개의 댓글