1. 문제 출처
https://www.acmicpc.net/problem/7562
2. 풀이
# 테스트 케이스 개수 받기
test_case_num = int(input())
# 나이트 8방향으로 이동 시 바뀌는 좌표 크기
# 원점이 좌측 상단 꼭지점이고 오른쪽, 아래쪽으로 갈 때 마다
# 1 씩 좌표가 늘어나고 그 반대는 1씩 줄어 든다
# x좌표 변화량 리스트
# x 좌표 변화량 리스트가 4인 이유는
# 원래 [-2,-1,1,2,-2,-1,1,2] 인데 -2,-1,1,2 반복이기 때문에 다음과 같이 했다.
dx = [-2,-1,1,2]
# x좌표 변화량 리스트
dy = [-1,-2,-2,-1,1,2,2,1]
# 결과 값 저장하는 리스트
results = []
# test_case_num 만큼 반복
for _ in range(test_case_num):
# 체스판 길이, 시작 좌표 , 목표좌표를 받는다.
board_w = int(input())
start = list(map(int,input().split()))
end = list(map(int,input().split()))
# 시작과 끝이 같다면 이동하지 않으므로 0을 추가하고 다음 케이스로 넘어간다.
if start == end :
results.append(0)
pass
else:
# queue에 시작점 좌표를 추가 한다.
queue = [[start[0],start[1]]]
# 몇 번 째에 방문 하였는지 알기 위한 2차원 리스트 선언 및 -1로 초기화
visited = [[-1 for _ in range(board_w)] for _ in range(board_w)]
# 시작점은 처음 방문 하는 곳 이므로 0으로 초기화 한다.
visited[start[0]][start[1]] = 0
# queue가 empty 될 때 까지 반복한다.
while queue:
# queue는 FIFO(선입선출) 이므로 pop(0)로 제일 처음에 넣은 값은 빼서 가지고 온다.
start = queue.pop(0)
x = start[0]
y = start[1]
# 8방향 으로 이동한 좌표를 구한다.
for i in range(8):
move_x = x + dx[i%4]
move_y = y + dy[i]
# 이동한 좌표가 목표 좌표이면 results에 결과를 저장 후 queue를 비운다
# 그 후 for i in range(8): 문을 break으로 나오면 queue가 clear 되었기 때문에 while문 반복이 종료된다.
if (move_x == end[0]) & (move_y == end[1]):
results.append(visited[x][y]+1)
queue.clear()
break
# 만약 움직인 좌표가 체스판을 내에 존재하고(is_in_boar & visited[move_x][move_y] == -1 같이 쓰면 indexError가 발생 할 수 있다.)
is_in_board = (0 <= move_x < board_w) & (0 <= move_y < board_w)
if is_in_board:
# 방문하지 않은 좌표일 경우
if (visited[move_x][move_y] == -1):
# 해당 좌표를 queue에 저장
queue.append([move_x,move_y])
# 해당 좌표의 최단 방문 횟수 저장
visited[move_x][move_y] = visited[x][y] + 1
for result in results:
print(result)
원래는 collections를 사용해서 하려고 했으나 리스트로 충분히 가능하여 사용하지 않았다.
'알고리즘 > 너비 우선 탐색(bfs)' 카테고리의 다른 글
16234-백준-인구이동 (0) | 2023.02.23 |
---|---|
18405-백준-경쟁적 전염 (0) | 2023.02.18 |
18352-백준-특정 거리의 도시 찾기 (0) | 2023.02.17 |
14502 - 백준 - 연구소 (0) | 2023.02.15 |
9205-백준-맥주 마시면서 걸어가기 (0) | 2023.02.07 |