✔ 풀이를 위한 아이디어
✔ 오답 코드 [틀렸습니다]
import sys
from collections import deque
N, M = map(int, sys.stdin.readline().split())
Map = []
for _ in range(N):
Map.append(list(map(int, sys.stdin.readline().strip())))
queue = deque()
queue.append((0, 0))
count = 0
success = 0
visited = [[0]*M for _ in range(N)]
visited[0][0] = 1
chance = 1
while queue:
if success:
break
count += 1
for _ in range(len(queue)):
x, y = queue.popleft()
if x == M-1 and y == N-1:
success = 1
break
if x > 0:
if Map[y][x-1] == 0 and not visited[y][x-1]:
queue.append((x-1, y))
visited[y][x-1] = 1
elif chance and not visited[y][x-1]:
queue.append((x-1, y))
chance = 0
if x < M-1:
if Map[y][x+1] == 0 and not visited[y][x+1]:
queue.append((x+1, y))
visited[y][x+1] = 1
elif chance and not visited[y][x+1]:
queue.append((x+1, y))
chance = 0
if y > 0:
if Map[y-1][x] == 0 and not visited[y-1][x]:
queue.append((x, y-1))
visited[y-1][x] = 1
elif chance and not visited[y-1][x]:
queue.append((x, y-1))
chance = 0
if y < N-1:
if Map[y+1][x] == 0 and not visited[y+1][x]:
queue.append((x, y+1))
visited[y+1][x] = 1
elif chance and not visited[y+1][x]:
queue.append((x, y+1))
chance = 0
if success:
print(count)
else:
print("-1")
✔ 정답 코드 [시간 초과 -> 해결]
import sys
from collections import deque
#import copy
N, M = map(int, sys.stdin.readline().split())
Map = []
for _ in range(N):
Map.append(list(map(int, sys.stdin.readline().strip())))
queue = deque()
queue.append((0, 0, 0)) # crack도 0이 안부신거, 1이 부신거
count = 0
success = 0
visited = [[[0]*M for _ in range(N)] for _ in range(2)]
visited[0][0][0] = 1 # 0이 벽 안 부신거, 1이 부신거 (맨 앞에 값)
while queue:
if success:
break
count += 1
for _ in range(len(queue)):
x, y, crack = queue.popleft()
if x == M-1 and y == N-1:
success = 1
break
if x > 0:
if Map[y][x-1] == 0 and not visited[crack][y][x-1]:
queue.append((x-1, y, crack))
visited[crack][y][x-1] = 1
elif Map[y][x-1] == 1 and not crack:
#visited[1] = copy.deepcopy(visited[0])
queue.append((x-1, y, 1))
visited[1][y][x-1] = 1
if x < M-1:
if Map[y][x+1] == 0 and not visited[crack][y][x+1]:
queue.append((x+1, y, crack))
visited[crack][y][x+1] = 1
elif Map[y][x+1] == 1 and not crack:
#visited[1] = copy.deepcopy(visited[0])
queue.append((x+1, y, 1))
visited[1][y][x+1] = 1
if y > 0:
if Map[y-1][x] == 0 and not visited[crack][y-1][x]:
queue.append((x, y-1, crack))
visited[crack][y-1][x] = 1
elif Map[y-1][x] == 1 and not crack:
#visited[1] = copy.deepcopy(visited[0])
queue.append((x, y-1, 1))
visited[1][y-1][x] = 1
if y < N-1:
if Map[y+1][x] == 0 and not visited[crack][y+1][x]:
queue.append((x, y+1, crack))
visited[crack][y+1][x] = 1
elif Map[y+1][x] == 1 and not crack:
#visited[1] = copy.deepcopy(visited[0])
queue.append((x, y+1, 1))
visited[1][y+1][x] = 1
if success:
print(count)
else:
print("-1")
if Map[y][x-1] == 0 and not visited[crack][y][x-1]:
queue.append((x-1, y, crack))
visited[crack][y][x-1] = 1
elif Map[y][x-1] == 1 and not crack: # and not visited[crack][y][x-1]
# visited[1] = copy.deepcopy(visited[0])
queue.append((x-1, y, 1))
visited[1][y][x-1] = 1
if Map[y][x-1] == 0 and not visited[crack][y][x-1]:
queue.append((x-1, y, crack))
visited[crack][y][x-1] = 1
"처음 내가 택한 방식은, chance라는 변수를 통해 벽 부수기 찬스를 썼는지 안썼는지를 판별하는 방식이었다. chance를 써서 벽을 부쉈을 때는 2차원 배열로 구성된 Map에서 원래라면 갈 수 없는 곳을 방문한 것이 되므로, 따로 visited에 체크하지 않았다.
그러나 이 방식을 택하게 되면, 밑의 반례를 해결할 수가 없었다. 반례 해결에 걸림돌이 되는 가장 근본적인 이유는, 벽을 뚫은 뒤에 방문한 지점을 벽을 뚫지 않는 경우에 방문할 수 없기 때문이었다. 따라서 visited를 이중화 하여서, 벽을 뚫은 경우와 뚫지 않은 경우를 구분해야 한다는 것을 깨달았다."
저랑 똑같은 고민을 거치셨네요. 글 잘 읽고 갑니다.