[백준] 16236 - 아기 상어
1. 문제
2. 개요
N * N 보드에 상어와 물고기가 있다. 상어는 자기보다 큰 물고기가 있는 칸으로 이동이 불가하다. 작은 물고기라면 먹을 수 있다. 아기 상어의 크기는 2이고 자신의 크기만큼의 물고기를 먹는다면 크기가 1씩 증가한다.
이동 규칙은 다음과 같다.
- 더 이상 먹을 수 있는 물고기가 공간에 없다면 아기 상어는 엄마 상어에게 도움을 요청한다.
- 먹을 수 있는 물고기가 1마리라면, 그 물고기를 먹으러 간다.
- 먹을 수 있는 물고기가 1마리보다 많다면, 거리가 가장 가까운 물고기를 먹으러 간다.
- 거리는 아기 상어가 있는 칸에서 물고기가 있는 칸으로 이동할 때, 지나야하는 칸의 개수의 최솟값이다.
- 거리가 가까운 물고기가 많다면, 가장 위에 있는 물고기, 그러한 물고기가 여러마리라면, 가장 왼쪽에 있는 물고기를 먹는다.
위와 같은 조건에서 물고기를 먹을 수 없을 때 까지의 이동 거리를 구하는 그래프 탐색 문제.
3. 코드 및 추가내용
처음 코드를 작성할 때는
- 거리가 가까운 물고기가 많다면, 가장 위에 있는 물고기, 그러한 물고기가 여러마리라면, 가장 왼쪽에 있는 물고기를 먹는다.
해당 조건을 단순히 현재 위치에서 $\uparrow$ , $\leftarrow$, $\rightarrow$, $\downarrow$ 순서대로 비교해서 먹이를 찾아낼 수 있을 거라고 생각했는데, 이게 잘못된 생각이었다.
// 9 - 상어, F - 먹이
0 9 0 F
F 0 0 0
0 0 0 0
0 0 0 0
인 경우 규칙대로라면 0행 4열의 먹이를 먹어야하지만, 작성한 코드에서는 대각선 아래의 먹이쪽으로 이동하는 오류가 있었다.
import sys
from collections import deque
N = int(sys.stdin.readline())
board = []
feed = []
_visited = [[0 for i in range(N)] for j in range(N)]
q = deque()
for i in range(N):
board.append(list(map(int, sys.stdin.readline().split())))
for j in range(N):
if board[-1][j] == 9:
board[i][j] = 0
start = [i, j]
bs_size = 2
ate = -1
feed.append(start)
dirY, dirX = [-1, 0, 0, 1], [0, -1, 1, 0]
ans = 0
visited = [[v[i] for i in v] for v in _visited]
visited[start[0]][start[1]] = 1
while feed:
feed.sort(key= lambda x : (x[0], x[1]))
q.clear()
q.append(feed[0])
feed.clear()
ate += 1
if ate >= bs_size:
bs_size += 1
ate = 0
ans += visited[q[0][0]][q[0][1]] - 1
board[q[0][0]][q[0][1]] = 0
visited = [[0 for _ in v] for v in _visited]
visited[q[0][0]][q[0][1]] = 1
tmp = deque()
while q:
now = q.popleft()
nowY, nowX = now[0], now[1]
for i in range(4):
nextY, nextX = nowY + dirY[i], nowX + dirX[i]
if nextY < 0 or nextY >= N or nextX < 0 or nextX >= N:
continue
if board[nextY][nextX] > bs_size:
continue
if visited[nextY][nextX]:
continue
if board[nextY][nextX] == bs_size:
pass
elif 0 < board[nextY][nextX] < bs_size:
feed.append([nextY, nextX])
visited[nextY][nextX] = visited[nowY][nowX] + 1
tmp.append([nextY, nextX])
if not q and not feed:
q = tmp
tmp = deque()
print(ans)
BFS를 행할 때, 같은 깊이의 위치를 모두 확인한 후, 먹이에 해당하는 칸이 있다면 이를 정렬하여 y, x순으로 오름차순 정렬한 첫 값을 목표지점으로 정하고 이동시키는 방법으로 구현하여 해결했다.
Comments