Algorithm/BaekJoon
[백준/Python] 1600번 - 말이 되고픈 원숭이
빵빵0
2023. 9. 10. 01:24
import sys
from collections import deque
input = sys.stdin.readline
# 상하좌우, 체스 나이트 이동
monkey = [[1,0],[0,1],[-1,0],[0,-1]]
horse = [[-2,-1], [-2,1],[-1,-2],[-1,2],[2,-1],[2,1],[1,-2],[1,2]]
K = int(input()) # 체스 나이트처럼 움직일 수 있는 횟수
W, H = map(int, input().split())
graph = [list(map(int, input().split())) for _ in range(H)]
## 특정 이동 방식에 횟수가 정해져 있을 때 3차원 배열 활용!
## 즉, 방문 처리 배열을 3차원으로 나타냄: visited[열][행][이동수]
# 난 재귀 생각하고 있었음,,ㅋ,,,
# (0,0) -> (W, H)
def bfs():
visited = [[[0]*(K+1) for _ in range(W)] for _ in range(H)]
# ** 순서가 층, 열, 행; 즉 W가 열 = y, H가 행 = x
queue = deque()
queue.append([0,0,0])
visited[0][0][0] = 1
while queue:
x, y, z = queue.popleft()
# 목표 지점에 도달하면 return (이 데이터가 pop되기 전에 이미 모든 경우의 수는 돌았음)
if x == H - 1 and y == W - 1:
return visited[x][y][z] - 1 # (0,0,0) 에서 1이었으므로 빼준다
# 상하 좌우로 이동
for i, j in monkey:
dx, dy = x + i, y + j
if 0 <= dx < H and 0 <= dy < W and not visited[dx][dy][z] and not graph[dx][dy]:
visited[dx][dy][z] = visited[x][y][z] + 1
queue.append([dx, dy, z])
# 말 이동 수보다 작을 경우에만 이동
if z < K:
for hi, hj in horse:
hx, hy = x + hi, y + hj
if 0 <= hx < H and 0 <= hy < W and not graph[hx][hy]:
# 움직이면 z + 1번째로 이동하는거니까 z+1층에 대입
if not visited[hx][hy][z+1]:
visited[hx][hy][z+1] = visited[x][y][z] + 1
queue.append([hx, hy, z+1])
return -1
print(bfs())