문제 링크: https://www.acmicpc.net/problem/11206
어렵다!
벽 부수고 이동하기는 bfs에서 자주 보이는 응용 (길 찾기, 최단경로 찾기)에 하나의 요소를 더 추가한 문제이다.
이 문제에서는 길찾기 도중 벽을 딱 한 번 뚫을 수 있다. 그리고 벽을 뚫지 않으면 진행 불가능한 경우도 존재한다.
모든 벽에 대해서 그것을 뚫어놓고 bfs 수행한 결과를 리스트로 저장, 마지막엔 리스트에서 min 값을 찾아내기
예제 2개에 대해서는 작동하나, 시간 초과가 된다.
맵의 최대 크기는 1000*1000
사이즈이므로, 그 맵이 전부 벽이라고 가정하면 1000*1000
회의 계산을 해야 한다.
따라서 이 방법은 일단 접근이 틀렸다.
bfs를 수행하며, 벽을 이미 부쉈는지, 부수지 않았는지를 기억해야 할 것 같은데...
잘 모르겠어서 이미 푼 사람들의 포스트를 알아봄.
# ㅠㅠ - 2트
# 2206 벽 부수고 이동하기
from sys import stdin
from collections import deque
input = stdin.readline
n, m = map(int, input().split())
ar = [[0] for _ in range(n)]
for i in range(n):
ar[i] = list(map(int, list(input().rstrip())))
visited = [[[0 for _ in range(2)] for _ in range(m)] for _ in range(n)]
# 3rd elem: 0이면 부수기 가능
# 1이면 부수기 불가
dx = [0, 0, -1, 1]
dy = [1, -1, 0, 0]
# elem 1st, 2nd - 좌표
# 3rd - isBroken & 거리 동시에
# 0 - 미방문, 양수 - 방문, 거리
result = -1
def bfs():
queue = deque([(0, 0, 0)])
visited[0][0][0] = 1
while queue:
cur = queue.popleft()
isBroken = cur[2]
if cur[0] == n-1 and cur[1] == m-1:
result = visited[cur[0]][cur[1]][isBroken]
return result # 탐색 종료
for d in range(4):
xx = cur[0] + dx[d]
yy = cur[1] + dy[d]
if 0 <= xx and xx < n and 0<= yy and yy < m and visited[xx][yy][isBroken] == 0:
if ar[xx][yy] == 0: # 전진 가능
queue.append((xx, yy, isBroken))
visited[xx][yy][isBroken] = visited[cur[0]][cur[1]][isBroken] + 1
else: # 전진 불가
if not isBroken: # 벽부수기 가능
queue.append((xx, yy, 1))
visited[xx][yy][1] = visited[cur[0]][cur[1]][isBroken] + 1
# 벽부수기 불가 - 더이상 진행 안 됨, 처리 할 것 없음.
return -1
print(bfs())