[백준] 7562 : 나이트의 이동 - Python

Chooooo·2023년 2월 12일
0

알고리즘/백준

목록 보기
50/182
post-thumbnail

나이트의 이동

체스판 위에 한 나이트가 놓여져 있다. 나이트가 한 번에 이동할 수 있는 칸은 아래 그림에 나와있다. 나이트가 이동하려고 하는 칸이 주어진다. 나이트는 몇 번 움직이면 이 칸으로 이동할 수 있을까?

입력

입력의 첫째 줄에는 테스트 케이스의 개수가 주어진다.

각 테스트 케이스는 세 줄로 이루어져 있다. 첫째 줄에는 체스판의 한 변의 길이 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 거리 리스트에 표시한다. 그리고 원하는 위치에 도착하면 탈출하면 된다 !

profile
back-end, 지속 성장 가능한 개발자를 향하여

0개의 댓글