출처 : 백준 #2206
시간 제한 | 메모리 제한 |
---|---|
2초 | 192MB |
N×M의 행렬로 표현되는 맵이 있다. 맵에서 0은 이동할 수 있는 곳을 나타내고, 1은 이동할 수 없는 벽이 있는 곳을 나타낸다. 당신은 (1, 1)에서 (N, M)의 위치까지 이동하려 하는데, 이때 최단 경로로 이동하려 한다. 최단경로는 맵에서 가장 적은 개수의 칸을 지나는 경로를 말하는데, 이때 시작하는 칸과 끝나는 칸도 포함해서 센다.
만약에 이동하는 도중에 한 개의 벽을 부수고 이동하는 것이 좀 더 경로가 짧아진다면, 벽을 한 개 까지 부수고 이동하여도 된다.
한 칸에서 이동할 수 있는 칸은 상하좌우로 인접한 칸이다.
맵이 주어졌을 때, 최단 경로를 구해 내는 프로그램을 작성하시오.
첫째 줄에 N(1 ≤ N ≤ 1,000), M(1 ≤ M ≤ 1,000)이 주어진다. 다음 N개의 줄에 M개의 숫자로 맵이 주어진다. (1, 1)과 (N, M)은 항상 0이라고 가정하자.
첫째 줄에 최단 거리를 출력한다. 불가능할 때는 -1을 출력한다.
6 4
0100
1110
1000
0000
0111
0000
15
4 4
0111
1111
1111
1110
-1
BFS로 접근하였다.
처음에는 visited를 2차원 배열로 하여 계속 copy하여(재귀가 아니기때문에) 다음 큐에 넣고, 길이(d)를 1씩 증가시켜 나갔다.
crash
의 초기값을 1로 설정하고 벽(1)을 만났을 때 부술 수 있는 count로 삼았다.아래 참고자료를 보고 다시 코드를 작성했다.
참고자료
visited를 3차원 배열로 만든다.
# visited
n = 6, m = 4
[[[0, 0], [0, 0], [0, 0], [0, 0]],
[[0, 0], [0, 0], [0, 0], [0, 0]],
[[0, 0], [0, 0], [0, 0], [0, 0]],
[[0, 0], [0, 0], [0, 0], [0, 0]],
[[0, 0], [0, 0], [0, 0], [0, 0]],
[[0, 0], [0, 0], [0, 0], [0, 0]]]
[0, 0]
중 첫번째 원소는 벽을 부수지 않을 때 거리를 기록한다. 두 번째 원소는 벽을 부쉈을 때 거리를 기록한다.visited[nx][ny][crash]
에 값을 visited[x][y][crash]+1
로 준다. (crash 횟수가 1이든 0이든 상관 없다.)visited[nx][ny][crash+1]
에 값을 visited[x][y][crash]+1
로 준다.# 백준 2206번 벽 부수고 이동하기
from sys import stdin
from collections import deque
import copy
input = stdin.readline
# n, m, matrix 입력받기
n, m = map(int, input().split())
matrix = []
one = []
final_one = []
for i in range(n):
string = input().rstrip()
temp = []
for j in range(len(string)):
s = int(string[j])
temp.append(s)
if s == 1:
one.append((i, j))
matrix.append(temp)
# 동 남 서 북
dx = [0, +1, 0, -1]
dy = [+1, 0, -1, 0]
start = (0, 0, 0) # x = 0, y = 0, d = 1, crash = 0
def bfs(start):
answer = int(1e9)
global matrix
# global visited
visited = [[[0]*2 for _ in range(m)]for _ in range(n)]
visited[0][0][0] = 1
q = deque([start])
while q:
x, y, crash= q.popleft()
if x == n-1 and y == m-1:
answer = min(answer, visited[x][y][crash])
return answer
for i in range(4):
nx = x+dx[i]
ny = y+dy[i]
if 0 <= nx < n and 0 <= ny < m:
if matrix[nx][ny] == 0 and visited[nx][ny][crash] == 0:
q.append((nx, ny, crash))
visited[nx][ny][crash] = visited[x][y][crash] + 1
elif matrix[nx][ny] == 1 and crash == 0:
q.append((nx, ny, crash+1))
visited[nx][ny][crash+1] = visited[x][y][crash] + 1
return False
result = bfs(start)
if result:
print(result)
else:
print(-1)