: 이전에 '미로 찾기' 문제와 똑같은 문제지만, 거기에 목수가 하나의 장애물을 부술 수 있다는 조건이 추가된 문제이다. 특정 좌표 x,y에서 z,a까지의 '최단거리'를 구하되, 중간에 1로 표현된 장애물이 있는데, 이 장애물 중에 하나를 부술 수 있는 조건이 추가된 것이다.
: 이미 BFS를 통해서 최단거리를 구할 수 있는 설계부분은 이전 문제에서 해봤으므로, 여기서는 장애물을 하나 부술수 있다는 조건을 어떻게 설계 및 구현해낼지를 고민해본다.
import copy
n,m = map(int, input().split())
board = []
# 경계 설정을 이번엔 1로하면 장애물로 인식할 수 있으니 -1로
for i in range(n):
board.append([-1] + list(map(int,input().split())) + [-1])
limit_line = [[-1 for i in range(m+2)]]
board = limit_line + board + limit_line
root = (n, 1)
queue = [root]
path = {}
path[root] = 0
cheat_way = []
copy_board = copy.deepcopy(board)
copy_board[n][1] = -1
while len(queue) != 0:
top = queue.pop(0)
up = (top[0]-1, top[1])
right = (top[0], top[1]+1)
down = (top[0]+1, top[1])
left = (top[0], top[1]-1)
next_arr = []
for el in [up,right,down,left] :
if copy_board[el[0]][el[1]] == 0:
now_len = path[top] + 1
if now_len == 1:
now_len = "1"
copy_board[el[0]][el[1]] = now_len
path[el] = path[top] + 1
next_arr.append(el)
elif copy_board[el[0]][el[1]] == 1:
try:
if path[el]:
continue
except:
path[el] = True
cheats_copy_board = copy.deepcopy(copy_board)
# 장애물을 만났을 때 또 BFS 탐색으로 끝까지 가보기
# 여태까지의 거리
copy_queue = [el]
copy_path = {}
copy_path[el] = path[top] + 1
cheats_copy_board[el[0]][el[1]] = path[top] + 1
while len(copy_queue) != 0:
copy_top = copy_queue.pop(0)
copy_up = (copy_top[0]-1, copy_top[1])
copy_right = (copy_top[0], copy_top[1]+1)
copy_down = (copy_top[0]+1, copy_top[1])
copy_left = (copy_top[0], copy_top[1]-1)
copy_next_arr = []
for idx in [copy_up,copy_right,copy_down,copy_left] :
if cheats_copy_board[idx[0]][idx[1]] == 0:
cheats_copy_board[idx[0]][idx[1]] = copy_path[copy_top] + 1
copy_path[idx] = copy_path[copy_top] + 1
copy_next_arr.append(idx)
else:
continue
copy_queue+= copy_next_arr
minimum = cheats_copy_board[1][m]
if minimum != 0:
cheat_way.append(minimum)
else:
continue
queue+= next_arr
cheat_way.append(copy_board[1][m])
result = min(cheat_way)
if result == 0:
cheat_way.remove(0)
print(min(cheat_way))
else:
print(result)
: 굉장히 복잡한 코드가 돼버렸는데.. 심지어 시간복잡도도 통과못했다.. 결국 못맞췄다 ㅠ
n,m = map(int, input().split())
board = []
for i in range(n):
board.append([-1] + list(map(int,input().split())) + [-1])
limit_line = [[-1 for i in range(m+2)]]
board = limit_line + board + limit_line
root = (n, 1)
queue = [root]
path = {}
path[root] = True
depth = {}
depth[root] = "0"
barrier = {}
copy_board = []
for row in board:
arr = []
for column in row:
arr.append(column)
copy_board.append(arr)
while len(queue) != 0:
top = queue.pop(0)
up = (top[0]-1, top[1])
childs = []
try:
if path[up]:
pass
except:
path[up]= True
childs.append(up)
right = (top[0],top[1]+1)
try:
if path[right]:
pass
except:
path[right]= True
childs.append(right)
down = (top[0]+1,top[1])
try:
if path[down]:
pass
except:
path[down]= True
childs.append(down)
left = (top[0],top[1]-1)
try:
if path[left]:
pass
except:
path[left]= True
childs.append(left)
for el in childs:
if board[el[0]][el[1]] == 1:
# 여기서 로직
try:
barrier[el].append(int(depth[top]))
except:
barrier[el] = [int(depth[top])]
continue
elif board[el[0]][el[1]] == 0:
copy_board[el[0]][el[1]] = int(depth[top]) +1
depth[el] = int(depth[top]) +1
queue.append(el)
else:
continue
# 여기서부터 반대로 하는 BFS
reverse_root = (1,m)
reverse_queue = [reverse_root]
path = {}
path[reverse_root] = True
depth[reverse_root] = "0"
while len(reverse_queue) != 0:
top = reverse_queue.pop(0)
childs = []
up = (top[0]-1, top[1])
try:
if board[up[0]][up[1]] == -1 or path[up]:
pass
except:
path[up]= True
childs.append(up)
right = (top[0],top[1]+1)
try:
if board[right[0]][right[1]] == -1 or path[right]:
pass
except:
path[right]= True
childs.append(right)
down = (top[0]+1,top[1])
try:
if board[down[0]][down[1]] == -1 or path[down]:
pass
except:
path[down]= True
childs.append(down)
left = (top[0],top[1]-1)
try:
if board[left[0]][left[1]] == -1 or path[left]:
pass
except:
path[left]= True
childs.append(left)
for el in childs:
if board[el[0]][el[1]] == 1:
try:
barrier[el].append(int(depth[top]))
except:
barrier[el] = [int(depth[top])]
continue
elif board[el[0]][el[1]] == 0:
depth[el] = int(depth[top]) + 1
reverse_queue.append(el)
else:
continue
barrier_min = copy_board[1][m]
if barrier_min == 0:
barrier_min = n*m
for arr in barrier.values():
if len(arr) == 1:
continue
else:
if sum(arr)+2 < barrier_min:
barrier_min = sum(arr)+2
print(barrier_min)