백준 2206 문제 링크: https://www.acmicpc.net/problem/2206
📑 문제 설명
1. NxM 행렬이 주어짐
2. 행렬 내에서 0은 이동할 수 있는 곳, 1은 벽으로 이동할 수 없음
3. (1, 1) 위치에서 시작하여 (N, M)으로 도착하는 최단 거리를 구해야 함
4. 그러나 벽을 부수고 갈 때 이동거리가 훨씬 짧아진다면 1회만 벽을 부술 수 있음
체크 포인트
1. 상하좌우로만 이동 가능하며 이동 시 1씩 추가됨
2. 시작점과 끝점에 도달할 경우에도 1씩 추가됨(이동거리 + 시작점 + 끝점)
입력: 첫번째 줄에 N, M이 주어지고 두번째 줄부터 행령이 주어짐
출력: 최단 거리
💡 문제 해결 방법
알고리즘: BFS
알고리즘 선택 이유
1. 최단거리를 구하는 문제이므로 BFS 사용
2. 벽을 부신 것에 대한 여부를 체크해야 함 --> 이 때 visit 배열을 3차원으로 만들어 queue에서 pop한 원소가 벽을 이미 한 번 부시고 방문하는 상태인지, 아니면 아직 벽을 부시지 않은 상태인지 체크
예외처리
1. DFS 종료 조건: N,M에 도달하거나 도달할 방법이 없을 경우 --> 경로가 없을 경우
2. 벽을 부셨는지 여부를 저장하는 변수 설정
스터디 내용
💻 코드
import sys
from collections import deque
n, m = list(map(int, sys.stdin.readline().split()))
graph = [[0 for x in range(m)] for x in range(n)]
for i in range(n):
temp = sys.stdin.readline()
for j in range(m):
graph[i][j]= int(temp[j])
visit = [[[False, False] for x in range(1002)] for x in range(1002)]
def bfs():
queue = deque([(0, 0, 0, 0)]) # x, y, break 횟수, dist
visit[0][0][0] = True
visit[0][0][1] = True
while(queue):
x, y, breakable, dist = queue.popleft()
if x == n-1 and y ==m-1:
print(dist+1)
return
adj_list = [[x+1, y], [x-1, y], [x, y+1], [x, y-1]]
for point in adj_list:
nx, ny = point
if nx >=0 and nx<n and ny>=0 and ny<m and visit[nx][ny][breakable] == False:
if graph[nx][ny] == 0:
visit[nx][ny][breakable] = True
queue.append((nx, ny, breakable, dist +1))
else:
if breakable == 0:
visit[nx][ny][breakable] = True
queue.append((nx, ny, 1, dist+1))
print(-1)
bfs()
💟 추가적으로 알게 된 점