너비 우선 탐색(bfs), 그래프 이론(graphs), 그래프 탐색(graph_traversal), 구현(implementation), 시뮬레이션(simulation)
N×N 크기의 공간에 물고기 M마리와 아기 상어 1마리가 있다. 공간은 1×1 크기의 정사각형 칸으로 나누어져 있다. 한 칸에는 물고기가 최대 1마리 존재한다.
아기 상어와 물고기는 모두 크기를 가지고 있고, 이 크기는 자연수이다. 가장 처음에 아기 상어의 크기는 2이고, 아기 상어는 1초에 상하좌우로 인접한 한 칸씩 이동한다.
아기 상어는 자신의 크기보다 큰 물고기가 있는 칸은 지나갈 수 없고, 나머지 칸은 모두 지나갈 수 있다. 아기 상어는 자신의 크기보다 작은 물고기만 먹을 수 있다. 따라서, 크기가 같은 물고기는 먹을 수 없지만, 그 물고기가 있는 칸은 지나갈 수 있다.
아기 상어가 어디로 이동할지 결정하는 방법은 아래와 같다.
아기 상어의 이동은 1초 걸리고, 물고기를 먹는데 걸리는 시간은 없다고 가정한다. 즉, 아기 상어가 먹을 수 있는 물고기가 있는 칸으로 이동했다면, 이동과 동시에 물고기를 먹는다. 물고기를 먹으면, 그 칸은 빈 칸이 된다.
아기 상어는 자신의 크기와 같은 수의 물고기를 먹을 때 마다 크기가 1 증가한다. 예를 들어, 크기가 2인 아기 상어는 물고기를 2마리 먹으면 크기가 3이 된다.
공간의 상태가 주어졌을 때, 아기 상어가 몇 초 동안 엄마 상어에게 도움을 요청하지 않고 물고기를 잡아먹을 수 있는지 구하는 프로그램을 작성하시오.
from collections import deque
import sys
input = sys.stdin.readline
def eat_fish(sx, sy, distance, Map):
global size, eat, time
Map[sx][sy] = 0
fish_far = 10000
x, y = -1, -1
for i in range(n):
for j in range(n):
if 0 < Map[i][j] < size and 0 < distance[i][j] < fish_far:
fish_far = distance[i][j]
x, y = i, j
if x == -1 and y == -1: return
Map[x][y] = 9
eat += 1
time += distance[x][y]
if size == eat:
size += 1
eat = 0
def check_dis(sx, sy):
q = deque()
q.append([sx, sy])
distance = [[-1] * n for _ in range(n)]
distance[sx][sy] = 0
while q:
x, y = q.popleft()
for k in range(4):
nx = x + dx[k]
ny = y + dy[k]
if not(0 <= nx < n and 0 <= ny < n): continue
if distance[nx][ny] != -1: continue
if Map[nx][ny] > size: continue
distance[nx][ny] = distance[x][y] + 1
q.append([nx, ny])
return distance
n = int(input())
size = 2
eat = 0
dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]
Map = [list(map(int, input().split())) for _ in range(n)]
cnt = 0
play = False
for i in range(n):
for j in range(n):
if 0 < Map[i][j] < size:
cnt += 1
if Map[i][j] == 9:
start = [i, j]
if cnt >= 1:
play = True
distance = check_dis(start[0], start[1])
time = 0
while play:
cnt = 0
eat_fish(start[0], start[1], distance, Map)
for i in range(n):
for j in range(n):
if 0 < Map[i][j] < size and Map[i][j] != 9:
cnt += 1
if Map[i][j] == 9:
start = [i, j]
if cnt >= 1:
play = True
else:
play = False
distance = check_dis(start[0], start[1])
for i in Map:
if 9 in i:
play = True
break
else:
play = False
print(time)