Problem Link
https://www.hackerrank.com/challenges/knightl-on-chessboard/problem?isFullScreen=true
직각 형태로 움직일 수 있는 체스 말(knight)을 이용하여, 크기의 행렬에서 부터 까지 말의 최소 이동 횟수를 구하는 문제
1. 너비 우선 탐색 (Breadth-First Search)
그림 출처: Wikipedia
def bfs(n, i, j):
checkVisit = [[0] * n for _ in range(n)]
queue = [[0, 0]]
dx, dy = [i, i, -i, -i, j, -j, j, -j], [j, -j, j, -j, i, i, -i, -i]
while queue:
px, py = queue.pop(0)
for p in range(8):
nx, ny = px + dx[p], py + dy[p]
if 0 <= nx < n and 0 <= ny < n and checkVisit[nx][ny] == 0:
queue.append([nx, ny])
checkVisit[nx][ny] = checkVisit[px][py] + 1
return -1 if checkVisit[n - 1][n - 1] == 0 else checkVisit[n - 1][n - 1]
def knightlOnAChessboard(n):
result = [[0] * (n - 1) for _ in range(n - 1)]
for i in range(1, n):
for j in range(i, n):
val = bfs(n, i, j)
result[i - 1][j - 1], result[j - 1][i - 1] = val, val
return result
📌 코드 구현 설명
- 반복문을 사용하여 발생할 수 있는 모든 경우를 탐색함 (
BFS
알고리즘 이용)
- 이므로, 절반만 탐색
BFS
함수에서 의 방문 노드 확인 및 이동 횟수 계산을 위해checkVisit
이라는 행렬을 생성
- 는 다음 위치인
checkVisit[i][j]
의 값이 0일 때만 이동하며, 이동한 이후에는checkVisit[i][j]
에 이전 단계까지의 이동 횟수에1
을 더하여 저장- 모든 경우를 탐색한 후, 최종적으로
checkVisit[n-1][n-1]
의 값이0
이 아니라면checkVisit[n-1][n-1]
에 저장된 값을return
,0
이라면-1
을return