가장 가까운 물고기는 BFS로 찾는다. 코드 내에서 fishes 리스트가 그것이다.
새로운 물고기를 먹을 때마다 상어의 위치가 변경되므로 fishes 리스트를 매번 갱신한다.
itemgetter를 이용해 물고기를 거리, row, col 순으로 손쉽게 정렬해줄 수 있다.
상어의 크기가 증가하는 규칙이 상어의 크기 += 물고기의 크기가 아니라,
상어 크기=지금까지 먹은 누적 물고기 갯수(in_belly) 일때마다 상어의 크기가 1씩 늘어난다는 점에 유의하자. 당연히 상어 크기가 늘어났으면 in_belly를 0으로 초기화해야 답이 나온다.
import sys from collections import deque from operator import itemgetter def get_distance(shark): fishes = [] visited = [[0] * N for _ in range(N)] visited[shark[ROW]][shark[COL]] = 1 dx = [0, 0, 1, -1] dy = [1, -1, 0, 0] queue = deque([[shark[ROW], shark[COL], 0]]) while queue: r, c, dist = queue.popleft() for i in range(4): next_r = r + dx[i] next_c = c + dy[i] if 0 <= next_r < N and 0 <= next_c < N: if not visited[next_r][next_c]: if board[next_r][next_c] <= shark[SIZE]: # 지나갈 수 있는 물고기 if 0 < board[next_r][next_c] < shark[SIZE]: # 먹을 수 있는 물고기 fishes.append([next_r, next_c, board[next_r][next_c], dist+1]) visited[next_r][next_c] = 1 queue.append([next_r, next_c, dist+1]) fishes.sort(key=itemgetter(DIST, 0, 1)) # 거리, row, column 순으로 정렬 return fishes def start(shark): global in_belly sec = 0 while True: fishes = get_distance(shark) if not fishes: # 물고기가 없으면 종료 print(sec) break prey = fishes[0] # 희생양 물고기 in_belly += 1 if shark[SIZE] == in_belly: shark[SIZE] += 1 in_belly = 0 shark = [prey[ROW], prey[COL], shark[SIZE]] # 상어 정보 업뎃 board[prey[ROW]][prey[COL]] = 0 sec += prey[DIST] del fishes[0] return if __name__ == '__main__': ROW, COL, SIZE, DIST = 0, 1, 2, 3 input = sys.stdin.readline N = int(input()) board = [list(map(int, input().split())) for _ in range(N)] shark_sz = 2 # 상어의 기본 크기는 2 in_belly = 0 # 누적된 먹은 물고기 갯수 for i in range(N): for j in range(N): if board[i][j] == 0: continue elif board[i][j] == 9: # 상어 shark_init = [i, j, shark_sz] board[i][j] = 0 # 나중에 물고기로 착각하지 않도록 0으로 변경 start(shark_init)
'알고리즘 > BFS와 DFS' 카테고리의 다른 글
15971번. 두 로봇 (0) | 2020.04.21 |
---|---|
14501번. 퇴사 (1) | 2020.04.17 |
2178번. 미로 탐색 (0) | 2020.04.08 |
13460번. 구슬 탈출 2 (0) | 2019.12.31 |
2468번. 안전 영역 (0) | 2019.12.30 |