[Gold III]
https://www.acmicpc.net/problem/16236
16236번: 아기 상어
N×N 크기의 공간에 물고기 M마리와 아기 상어 1마리가 있다. 공간은 1×1 크기의 정사각형 칸으로 나누어져 있다. 한 칸에는 물고기가 최대 1마리 존재한다. 아기 상어와 물고기는 모두 크기를 가
www.acmicpc.net
풀이
우선 그래프 내에서 가장 가까운 칸을 찾기 때문에, BFS로 풀어야 하는 것은 바로 생각이 났고,
N <= 20
이기 때문에, 시간 복잡도를 거의 생각하지 않고, 그냥 빡구현 문제 느낌으로 풀이하면 된다.
그냥 구현 문제이므로, 자세한 풀이는 주석으로 대체.
AC.
from collections import deque N = int(input()) M = [] for _ in range(N): M.append(list(map(int, input().split()))) # 상어를 찾고, 상어 칸을 2로 설정. shark = () for i in range(N): for j in range(N): if M[i][j] == 9: shark = (i, j) dr = [1, 0, -1, 0] dc = [0, 1, 0, -1] def bfs(r, c): visited = [[0]*N for _ in range(N)] # 1로 설정해야 시작한 곳을 queue에 append하지 않음. visited[r][c] = 1 deq = deque([(r, c)]) prey = [] while deq: i, j = deq.popleft() for k in range(4): nr = i + dr[k] nc = j + dc[k] # 범위 내인지, 이미 visit했는지 확인 if 0 <= nr < N and 0 <= nc < N and visited[nr][nc] == 0: # 먹을 수 있으면 if M[r][c] > M[nr][nc] and M[nr][nc] != 0: # 이전 visited보다 +1 함으로써, 몇 초가 걸리는 지 저장 visited[nr][nc] = visited[i][j]+1 prey.append((visited[nr][nc]-1, nr, nc)) # 숫자가 같을 때 (지나갈 수만 있음) elif M[r][c] == M[nr][nc]: visited[nr][nc] = visited[i][j]+1 deq.append((nr, nc)) # 빈 칸일 때 elif M[nr][nc] == 0: visited[nr][nc] = visited[i][j]+1 deq.append((nr, nc)) # 먹을 수 있는 리스트를 반환. 가장 가까운 것 -> 가장 위 -> 가장 왼쪽 순으로 나열. return list(sorted(prey, key=lambda x: (x[0], x[1], x[2]))) second = 0 size = 2 eat = 0 while True: r, c = shark M[r][c] = size prey = list(bfs(r, c)) # 먹이가 없으면 break if not prey: break # 먹이가 있으면, 최우선순위의 먹이를 먹음. sec, nr, nc = prey[0] second += sec eat += 1 if eat == size: size += 1 eat = 0 M[r][c] = 0 shark = (nr, nc) print(second)