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

입력
입력의 첫째 줄에는 테스트 케이스의 개수가 주어진다.
각 테스트 케이스는 세 줄로 이루어져 있다. 첫째 줄에는 체스판의 한 변의 길이 l(4 ≤ l ≤ 300)이 주어진다. 체스판의 크기는 l × l이다. 체스판의 각 칸은 두 수의 쌍 {0, ..., l-1} × {0, ..., l-1}로 나타낼 수 있다. 둘째 줄과 셋째 줄에는 나이트가 현재 있는 칸, 나이트가 이동하려고 하는 칸이 주어진다.
출력
각 테스트 케이스마다 나이트가 최소 몇 번만에 이동할 수 있는지 출력한다.
구글링한 코드를 변형하여 시간을 소폭 단축시켰다.
예제 입력 1
3
8
0 0
7 0
100
0 0
30 50
10
1 1
1 1
예제 출력 1
5
28
0
2. 접근 방법
BFS를 이용해 푼다. 체스판의 각 칸에 몇 번째 이동인지 횟수를 저장하여, 정답인 경로를 찾았을 때 그 횟수를 반환한다.
3. 코드
from collections import deque
import sys
input = sys.stdin.readline
# 이동할 수 있는 8가지 경우의 수
dx = [-1, -2, -2, -1, 1, 2, 2, 1]
dy = [2, 1, -1, -2, -2, -1, 1, 2]
def bfs(sx, sy, ax, ay):
# 현재 위치 = 이동할 위치인 경우
if ax==sx and ay==sy:
print(0)
return
q = deque()
q.append([sx, sy])
s[sx][sy] = 1 # 이때는 이동하지 않았지만 0이면 방문했는지 안했는지 확인 어려우므로 1부터 시작
while q:
# a, b : 먼저 이동한 좌표부터 꺼냄
a, b = q.popleft()
for i, j in zip(dx,dy):
# 이동하려는 좌표를 x,y에 각각 대입
x = a + i
y = b + j
# 체스판 내의 공간이면서, 아직 방문하지 않은 칸일 때 True
if 0 <= x < n and 0 <= y < n and s[x][y] == 0:
# 목적 좌표와 같다면 이동횟수 프린트.
if [x,y] == [ax,ay]:print(s[a][b]); q = 0; break;
q.append([x, y])
s[x][y] = s[a][b] + 1
# 실행 코드
t = int(input())
for i in range(t):
n = int(input())
sx, sy = map(int, input().split())
ax, ay = map(int, input().split())
s = [[0] * n for i in range(n)]
bfs(sx, sy, ax, ay)
4. 결과
5. 참고
https://pacific-ocean.tistory.com/311
[백준] 7562번(python 파이썬)
문제 링크: https://www.acmicpc.net/problem/7562 7562번: 나이트의 이동 문제 체스판 위에 한 나이트가 놓여져 있다. 나이트가 한 번에 이동할 수 있는 칸은 아래 그림에 나와있다. 나이트가 이동하려고 하
pacific-ocean.tistory.com
728x90
'TIL저장소' 카테고리의 다른 글
[백준/파이썬] 11650번 좌표 정렬하기 (0) | 2022.03.23 |
---|---|
[PyTorch] zero_grad(), model.zero_grad()와 optimizer.zero_grad() (1) | 2022.02.22 |
[리눅스] 상대경로, 절대경로, 리눅스 기본 명령어 (0) | 2022.01.02 |
[REST API] 참고할 만한 포스트 정리 (0) | 2022.01.02 |
[네이버 부스트코스]CS50 2019 모두를 위한 컴퓨터과학 6.데이터구조 (0) | 2021.06.28 |