체스판 위에 한 나이트가 놓여져 있다. 나이트가 한 번에 이동할 수 있는 칸은 아래 그림에 나와있다. 나이트가 이동하려고 하는 칸이 주어진다. 나이트는 몇 번 움직이면 이 칸으로 이동할 수 있을까?
입력의 첫째 줄에는 테스트 케이스의 개수가 주어진다.
각 테스트 케이스는 세 줄로 이루어져 있다. 첫째 줄에는 체스판의 한 변의 길이 l(4 ≤ l ≤ 300)이 주어진다. 체스판의 크기는 l × l이다. 체스판의 각 칸은 두 수의 쌍 {0, ..., l-1} × {0, ..., l-1}로 나타낼 수 있다. 둘째 줄과 셋째 줄에는 나이트가 현재 있는 칸, 나이트가 이동하려고 하는 칸이 주어진다.
각 테스트 케이스마다 나이트가 최소 몇 번만에 이동할 수 있는지 출력한다.
import sys
sys.stdin = open("input.text", "rt")
from collections import deque
input = sys.stdin.readline
#최소 몇번만에 이동 → 최단거리 생각
dx = [-1,1,-1,1,-2,2,-2,2]
dy = [-2,-2,2,2,-1,-1,1,1]
def BFS(a,b, c,d):
dq = deque()
dq.append((a,b))
ch[a][b] = 1 # 시작점 방문
while dq:
x,y = dq.popleft()
if x == c and y == d:
break
for i in range(8):
nx = x + dx[i]
ny = y + dy[i]
if 0<=nx<l and 0<=ny<l: #경계선
if ch[nx][ny] == 0:
ch[nx][ny] = 1
dis[nx][ny] = dis[x][y] + 1
dq.append((nx,ny))
T = int(input())
for _ in range(T):
l = int(input()) #체스판 한 변 길이
x,y = map(int, input().split()) #나이트 현재 있는 칸
ax,ay = map(int, input().split()) #이동하려고 하는 칸
ch = [[0] * l for _ in range(l)]
dis = [[0] * l for _ in range(l)]
BFS(x,y,ax,ay)
print(dis[ax][ay])
문제에서 체스의 현재 위치, 원하는 위치가 주어졌다. 그리고 최소 몇번만에 갈 수 있는지를 물어봤다. 이 경우에 그래프 + 최단거리 이므로 BFS로 풀어야 한다고 생각했어야 했다.
먼저 이 문제는 나이트가 총 8가지로 이동할 수 있기 때문에(뻗어나갈 수 있기 때문에) 방향벡터를 미리 저장해둔다.
또한 이제 시작점을 큐에 넣어준 후 BFS를 돌 것인데 8가지 방향 모두 확인하면서 해당 위치가 아직 방문 전이면서 + 경계선 내에 좌표라면 방문 표시 후에 거리를 dis 거리 리스트에 표시한다. 그리고 원하는 위치에 도착하면 탈출하면 된다 !