이동방법이 특이할 뿐이지, 최소경로로 목적지까지 가는 BFS 겠다!
근데 이제 구현을 열심히해야지.
이동방법도 dx, dy처럼 움직일 수 있는 방식을 배열로 주고 그 안에서 고르게 하면 될듯한데
이런 바둑판 문제에선, <모든 칸 = 노드 & 모든 노드는 1인 간선으로 연결되어있다> 고 생각하기
간선의 비용이 1로 동일하기때문에, BFS를 사용하여 최적해를 구할 수 있다.
from collections import deque
def get_next_pos(pos, board) :
next_pos = [] #반환 결과(이동 가능한 위치들)
pos = list(pos) # 현재 위치 정보를 리스트로 변환(집합->리스트)
pos1_x, pos1_y, pos2_x, pos2_y = pos[0][0], pos[0][1], pos[1][0], pos[1][1]
# (상,하,좌,우)로 이동하는 경우 처리
dx = [-1,0,0,0]
dy = [0,0,-1,1]
for i in range(4) :
pos1_next_x, pos1_next_y, pos2_next_x, pos2_next_y = pos1_x+dx[i], pos1_y+dy[i], pos2_x+dx[i], pos2_y+dy[i]
# 이동하고자 하는 두 칸이 비어있다면
if board[pos1_next_x][pos1_next_y] == 0 and board[pos2_next_x][pos2_next_y] == 0:
next_pos.append({(pos1_next_x, pos1_next_y), (pos2_next_x, pos2_next_y)})
# 현재 로봇이 가로로 놓여 있는 경우
if pos1_x == pos2_x :
for i in [-1, 1] : # 위쪽으로 회전하거나, 아래쪽으로 회전
if board[pos1_x+i][pos1_y] == 0 and board[pos2_x+i][pos2_y] == 0 : # 위쪽 혹은 아쪽 두 칸이 모두 비어있따면
next_pos.append({(pos1_x, pos1_y), (pos1_x+i, pos1_y)})
next_pos.append({(pos2_x, pos2_y), (pos2_x+i, pos2_y)})
# 현재 로봇이 세로로 놓여 있는 경우
elif pos1_y == pos2_y :
for i in [-1, 1] : #왼쪽으로 회전하거나, 오른쪽으로 회전
if board[pos1_x][pos1_y + i] == 0 and board[pos2_x][pos2_y+i] == 0 : #왼쪽 혹은 오른쪽 두 칸이 모두 비어있다면
next_pos.append({(pos1_x, pos1_y), (pos1_x, pos1_y+i)})
next_pos.append({(pos2_x, pos2_y), (pos2_x, pos2_y+i)})
# 현재 위치에서 이동할 수 있는 위치를 반환
return next_pos
def solution(board) :
# 맵의 외곽에 벽 패딩을 두는 형태로 맵 변형
n = len(board)
new_board = [[1]*(n+2) for _ in range(n+2)]
for i in range(n) :
for j in range(n) :
new_board[i+1][j+1] = board[i][j]
# 너비 우선 탐색 BFS 수행
q = deque()
visited = []
pos = {(1,1),(1,2)} # 시작 위치 설정
q.append((pos, 0))
visited.append(pos) # 방문처리
# 큐가 빌때까지 반복
while q :
pos, cost = q.popleft()
# (n,n) 위치에 로봇이 도달했다면, 최단 거리이므로 반환
if (n,n) in pos :
return cost
# 현재 위치에서 이동할 수 있는 위치 확인
for next_pos not in visited :
q.append((next_pos, cost+1))
visited.append(next_pos)
return 0
왕 .. 엄청 복잡하다
그래도
는 책에 적힌대로 유용하고 더 간단하게 푸는 좋은 방법이었다.
BFS는 1 만큼 움직일 수 있는 모든 node를 큐에 담아둔다. 다 담은 후에 차례대로 방문한다
라는 개념이 오히려 더 잘 머리에 박히게 됐다.