Skip to content

Commit a318a64

Browse files
committed
[BOJ] 16236 아기 상어 (G3)
1 parent 0eac7b9 commit a318a64

File tree

1 file changed

+104
-0
lines changed

1 file changed

+104
-0
lines changed

최어진/8주차/260217.py

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# 백준 16236번: 아기 상어 (3회차)
2+
3+
from collections import deque
4+
import sys
5+
6+
input = sys.stdin.readline
7+
8+
# N <= 20
9+
N = int(input())
10+
maps = [list(map(int, input().rstrip().split())) for _ in range(N)]
11+
12+
# 포인트
13+
# 1. 아기 상어는 자신과 작거나 같은 경우 지나칠 수 있음
14+
# 2. 아기 상어는 자신과 작은 경우 먹을 수 있음
15+
# 3. 아기 상어는 먹을 수 있는 먹이 중에서는 가장 가까운 먹이를 먹음
16+
# 4. 가장 가까운 먹이가 여러 개라면, Z 순서로 먹이를 먹음
17+
# 5. 먹을 수만 있다면, 크기가 더 작느냐는 중요치 않고 거리가 중요하다는 점 명심
18+
# 6. 이 때의 거리는 유클리디안 거리가 아닌, BFS 이동 거리라는 점 명심
19+
# 아이디어
20+
# 1. 현재 아기 상어로부터 BFS 수행, 먹을 수 있는 먹이 후보를 모두 선정 -> O(N^2)
21+
# 2. 먹을 수 있는 먹이 후보 중 가장 좌상에 있는 먹이를 먹음 -> O(N^2)
22+
# 3. 이 과정을 모든 먹이 개수만큼 반복 -> O(N^2)
23+
24+
moves = [
25+
[0, 1],
26+
[0, -1],
27+
[1, 0],
28+
[-1, 0]
29+
]
30+
31+
shark_r, shark_c = -1, -1
32+
shark_size = 2
33+
shark_eaten = 0
34+
for r in range(N):
35+
for c in range(N):
36+
if maps[r][c] == 9:
37+
maps[r][c] = 0
38+
shark_r, shark_c = r, c
39+
40+
def is_in_board(r, c):
41+
return 0 <= r < N and 0 <= c < N
42+
43+
def is_can_pass(r, c):
44+
global shark_size
45+
return maps[r][c] <= shark_size
46+
47+
def is_can_eat(r, c):
48+
global shark_size
49+
return 1 <= maps[r][c] < shark_size
50+
51+
def find_all_catchable_fishes(r, c):
52+
global shark_size
53+
q = deque()
54+
visited = [[404 for _ in range(N)] for _ in range(N)]
55+
candidates = []
56+
57+
q.append((r, c, 0))
58+
visited[r][c] = 0
59+
60+
while q:
61+
r, c, moved = q.popleft()
62+
63+
for dr, dc in moves:
64+
if is_in_board(r + dr, c + dc) and is_can_pass(r + dr, c + dc) and visited[r + dr][c + dc] > moved + 1:
65+
if is_can_eat(r + dr, c + dc):
66+
candidates.append((r + dr, c + dc, moved + 1))
67+
visited[r + dr][c + dc] = moved + 1
68+
else:
69+
q.append((r + dr, c + dc, moved + 1))
70+
visited[r + dr][c + dc] = moved + 1
71+
72+
return candidates
73+
74+
def find_one_fish_to_eat(candidates):
75+
candidates.sort(key=lambda x:(x[2], x[0], x[1]))
76+
return candidates[0]
77+
78+
answer = 0
79+
while True:
80+
candidates = find_all_catchable_fishes(shark_r, shark_c)
81+
# print(candidates)
82+
if len(candidates) == 0: break
83+
84+
fr, fc, fmoved = find_one_fish_to_eat(candidates)
85+
# print(fr, fc, fmoved)
86+
maps[fr][fc] = 0
87+
shark_r, shark_c = fr, fc
88+
answer += fmoved
89+
# print('---------------')
90+
# for row in maps:
91+
# print(row)
92+
# print('shark in', (shark_r, shark_c))
93+
94+
shark_eaten += 1
95+
if shark_eaten >= shark_size:
96+
shark_size += 1
97+
shark_eaten = 0
98+
# print('shark size is', shark_size)
99+
100+
# print('---------------')
101+
# print('answer:', answer)
102+
# print()
103+
104+
print(answer)

0 commit comments

Comments
 (0)