| 시간 제한 | 메모리 제한 | 제출 | 정답 | 맞힌 사람 | 정답 비율 |
|---|---|---|---|---|---|
| 1 초 | 256 MB | 66648 | 35756 | 26553 | 52.472% |
체스판 위에 한 나이트가 놓여져 있다. 나이트가 한 번에 이동할 수 있는 칸은 아래 그림에 나와있다. 나이트가 이동하려고 하는 칸이 주어진다. 나이트는 몇 번 움직이면 이 칸으로 이동할 수 있을까?

[입력]
입력의 첫째 줄에는 테스트 케이스의 개수가 주어진다.
각 테스트 케이스는 세 줄로 이루어져 있다. 첫째 줄에는 체스판의 한 변의 길이 l(4 ≤ l ≤ 300)이 주어진다. 체스판의 크기는 l × l이다. 체스판의 각 칸은 두 수의 쌍 {0, ..., l-1} × {0, ..., l-1}로 나타낼 수 있다. 둘째 줄과 셋째 줄에는 나이트가 현재 있는 칸, 나이트가 이동하려고 하는 칸이 주어진다.
[출력]
각 테스트 케이스마다 나이트가 최소 몇 번만에 이동할 수 있는지 출력한다.
from collections import deque
# 나이트가 이동할 수 있는 8가지 방향 정의
moves = [(-2, -1), (-1, -2), (1, -2), (2, -1), (2, 1), (1, 2), (-1, 2), (-2, 1)]
# BFS 함수
def bfs(start_x, start_y, target_x, target_y, board_size):
# 방문 여부를 저장하는 배열
visited = [[False] * board_size for _ in range(board_size)]
queue = deque([(start_x, start_y, 0)]) # (현재 x, y, 이동 횟수)
visited[start_x][start_y] = True
while queue:
x, y, moves_count = queue.popleft()
# 목표 지점에 도달한 경우
if x == target_x and y == target_y:
return moves_count
# 나이트의 모든 이동 방향 탐색
for dx, dy in moves:
nx, ny = x + dx, y + dy
if 0 <= nx < board_size and 0 <= ny < board_size and not visited[nx][ny]:
visited[nx][ny] = True
queue.append((nx, ny, moves_count + 1))
return -1 # 도달할 수 없는 경우
t = int(input())
for _ in range(t):
n = int(input())
start_x, start_y = map(int, input().split())
target_x, target_y = map(int, input().split())
if start_x == target_x and start_y == target_y:
print(0) # 시작점과 목표점이 같은 경우
else:
print(bfs(start_x, start_y, target_x, target_y, n))
BFS(너비 우선 탐색)는 주로 그래프나 트리 구조에서 최단 경로를 찾거나, 모든 가능한 경우를 탐색하는 문제에서 사용된다.
BFS는 한 레벨씩 탐색하며 가까운 노드부터 탐색을 진행하기 때문에, 경로를 찾는 데 있어 최단 경로를 보장할 수 있다.
1. 최단 경로 탐색 문제
2. 모든 가능한 경우 탐색
3. 트리의 레벨 탐색
4. 시뮬레이션 및 퍼즐 문제
bfs 문제는 보통 최단 경로 탐색 문제에서 자주 사용된다. 위에서 정리한 bfs가 자주 사용되는 문제들을 기억해뒀다가 생소한 문제가 나와도 풀 수 있도록 공부해야겠다는 생각이 들었다. dfs, bfs의 알고리즘에 대해 정확히 이해하고 넘어갈 수 있어서 좋은 시간이었다.