[파이썬] 백준 16959 : 체스판 여행 1 (플레5)
풀이
방향성 생각
- 다차원 BFS
- N=10인데 위치만으로 visit 배열을 만들게 되면 방문 처리가 제대로 되지 않는다.
- 위치 + 현재 사용하는 말 + 방문한 숫자(현재 위치가 아니라, 1~N^2까지 방문 중 몇번째인지)
전체코드
from collections import deque
inside = lambda x,y : 0<=x<N and 0<=y<N
N = int(input())
arr = [list(map(int,input().split())) for _ in range(N)]
# 시작 / 끝 위치 설정
for i in range(N):
for j in range(N):
if arr[i][j] == 1:
sx,sy = j,i
if arr[i][j] == N**2:
ex,ey = j,i
# 각 말 별로 위치 지정
dire = {0:[(x,y) for x in (1,2,-1,-2) for y in (1,2,-1,-2) if abs(x)+abs(y)==3], # 나이트
1:[(x,y) for x in (1,-1) for y in (1,-1)], # 비숍
2:[(1,0),(-1,0),(0,-1),(0,1)]} # 룩
# V[말][현재숫자][y][x]
V = [[[[-1]*N for _ in range(N)] for _ in range(N**2+1)] for _ in range(3)]
for i in range(3):
V[i][1][sy][sx] = 0
Q = deque([tuple((sx,sy,0,i,1)) for i in range(3)]) # x,y,t,말,현재숫자
while Q:
x,y,t,c,v = Q.popleft()
# 말 바꾸기 : 다른 말로 v까지 찾은 상태에서 해당 좌표 x,y에 접근 안했을 때 다른 말로 변경
for nc in range(3):
if V[nc][v][y][x] == -1 and c!=nc:
Q.append((x,y,t+1,nc,v))
V[nc][v][y][x] = t+1
# 이동
for dx,dy in dire[c]:
for step in range(1,N):
nx,ny = x+dx*step,y+dy*step
# 해당 방향으로 이동 못하게 되면 룩, 비숍 탈출 or 나이트는 1 step만 가능
if not inside(nx,ny) or v==N**2 or (c==0 and step>1):
break
# v까지 찾은 상태에서 다음 숫자 v+1을 방문
if V[c][v+1][ny][nx] == -1 and arr[ny][nx] == v+1:
Q.append((nx,ny,t+1,c,v+1))
V[c][v+1][ny][nx] = t+1
# v까지 찾은 상태에서 다음 숫자를 못찾은 경우
elif V[c][v][ny][nx] == -1 and arr[ny][nx] != v+1:
Q.append((nx,ny,t+1,c,v))
V[c][v][ny][nx] = t+1
print(min(V[i][-1][ey][ex] for i in range(3)))
코멘트
- 이왜플?
'Algorithm > Graph' 카테고리의 다른 글
[파이썬] 백준 16398 : 행성 연결 (골드4) (0) | 2025.01.02 |
---|---|
[파이썬] 백준 1922 : 네트워크연결 (골드4) (0) | 2025.01.01 |
[파이썬] 백준 16952 : 체스판 여행 2 (플레4) (0) | 2024.12.07 |
[파이썬] 백준 16930 : 달리기 (플레3) (0) | 2024.11.29 |
[파이썬] 백준 17267: 상남자 (플레5) (0) | 2024.11.28 |
[파이썬] 백준 1981 : 배열에서 이동 (플레5) (0) | 2024.11.28 |
[파이썬] 백준 2325 : 개코전쟁 (플레5) (0) | 2024.11.27 |
댓글