백준-16236-아기 상어:shark:

업데이트:

문제

아기 상어:shark:

풀이

문제조건 해석

아기 상어가 물고기를 잡아먹을 때 걸리는 총 시간 구하기

현재 상태를 변경해가면서 조건에 따라 BFS해줘야 한다.

  • 먹을 수 있는 물고기 없으면 종료

    • 자신보다 작은 물고기만 먹을 수 있다.
  • 가장 가까운 물고기를 먹는다

    • 거리가 같다면 가장 위에 있는 물고기, 그러한 물고기가 여러마리라면, 가장 왼쪽에 있는 물고기
  • 물고기를 먹을 때마다 크기가 증가한다.

알고리즘

아기 상태의 상태(현재위치, 크기)를 업데이트해가면서 BFS한다.

먹을 물고기 조건은 최단거리뿐만 아니라 가장 위, 가장 왼쪽 조건도 만족해야 한다.

  • (거리, i좌표, j좌표) 순의 우선순위를 가지는 최소 우선순위 큐를 이용해야 한다.

  • 일반 큐로 구현하게 되면 거리가 증가할 때마다 좌표값을 기준으로 정렬해줘야 한다.

  • 3 0 1 2 3
    2 1 0 0 0
    0 0 0 0 0
    (숫자는 거리를 나타낸다)
    --> 오른쪽에 있는 3보다 왼쪽에 있는 3을 먼저 방문해야 한다
    

코드

from sys import stdin
import heapq
input = stdin.readline

n = int(input().rstrip())
ocean = []
for _ in range(n):
    ocean.append([int(x) for x in input().rstrip().split()])

for i in range(n):
    for j in range(n):
        if ocean[i][j] == 9:
            si, sj = i, j
            ocean[i][j] = 0  # 시작 위치 0으로 변경


def bfs(si, sj, size):
    """
    물고기를 찾아 먹는다.
    """
    time = 0
    queue = [(time, si, sj)]
    visited = {(si, sj)}
    while queue:
        for _ in range(len(queue)):
            time, i, j = heapq.heappop(queue)
            if 0 < ocean[i][j] < size:  # 자신보다 작으면 먹을 수 있다
                ocean[i][j] = 0
                return i, j, time  # 현재 좌표와 움직인 시간 반환

            for di, dj in [(-1, 0), (0, -1), (0, 1), (1, 0)]:
                if not (0 <= i+di < n and 0 <= j+dj < n):
                    continue
                if ocean[i+di][j+dj] <= size \
                        and (i+di, j+dj) not in visited:  # 자기보다 크면 지날 수 없다.
                    visited.add((i+di, j+dj))
                    heapq.heappush(queue, (time+1, i+di, j+dj))
        time += 1
    return si, sj, 0  # 종료 조건, 움직이지 않은 상태


answer = 0
size = 2
eaten = 0 # 먹은 물고기 수
while True:
    si, sj, time = bfs(si, sj, size)
    if time == 0:
        break
    answer += time
    eaten += 1
    if eaten == size:
        size += 1
        eaten = 0
print(answer)

배운점

  • 거리를 우선순위로 하는 최소 힙은 일반 큐를 이용한 BFS와 동일하다.
  • BFS에서 특정 조건을 우선으로 탐색해야 할 때는 우선순위 큐를 고려하자.

댓글남기기