⭐️
from collections import deque
# BFS
def bfs():
q = deque()
distList, minDist = [], 987654321
q.append([sharkRow, sharkCol, 0])
visit = [[False for i in range(N)] for j in range(N)]
visit[sharkRow][sharkCol] = True
while q:
item = q.popleft()
curRow, curCol, dist = item[0], item[1], item[2]
for dx, dy in [(0, 1), (0, -1), (1, 0), (-1, 0)]:
new_row, new_col = curRow + dx, curCol + dy
if 0 <= new_row < N and 0 <= new_col < N and not visit[new_row][new_col]:
if sharkSize >= maps[new_row][new_col]:
visit[new_row][new_col] = True
if 1 <= maps[new_row][new_col] < sharkSize:
minDist = dist
distList.append((dist+1, new_row, new_col))
else:
q.append([new_row, new_col, dist + 1])
if distList:
distList.sort()
return distList[0]
else:
return False
def update(updateRow, updateCol):
global fishSum, sharkRow, sharkCol, sharkSize
maps[sharkRow][sharkCol] = 0
sharkRow, sharkCol = updateRow, updateCol
fishSum += 1
maps[sharkRow][sharkCol] = 9
# 상어 몸집 업데이트
if sharkSize <= fishSum:
fishSum -= sharkSize
sharkSize += 1
N = int(input())
maps = [list(map(int, input().split())) for i in range(N)]
count, fishCount = 0, 0
sharkSize, fishSum = 2, 0
sharkRow, sharkCol = -1, -1
fishRow, fishCol = -1, -1
for rowIdx, i in enumerate(maps):
for idx, j in enumerate(i):
if j == 9:
sharkRow, sharkCol = rowIdx, idx
break
while True:
value = bfs()
# 먹을 수 있는 물고기가 존재
if value:
moved, targetX, targetY = value[0], value[1], value[2]
update(targetX, targetY)
count += moved
# 먹을 수 없음
else:
break
print(count)
구현 문제를 풀 때, 자꾸 예외 상황을 처리하려고 조건문을 거는 습관이 있는데
그러면 로직이 너무 복잡해지고 디버깅도 까다롭고 시간도 많이 걸린다.
예를 들면, 처음에 풀 때 일단 맵에 물고기가 존재하는지 search 함수
로 확인을 하고 존재한다면 bfs
를 돌리는데 여기서 또 후보가 1마리인 경우와 그 이상인 경우로 나눠서 풀고 이런 식이었다.
하지만 그냥 bfs
함수가 저 기능들을 한번에 할 수 있도록 살짝만 응용해 주면 된다. bfs
의 반환값이 false 면 아무것도 못찾았다. 그리고 값이 있는 경우는 (최소거리, target_x, target_y) 정보를 차례로 sorting 된 값을 넘기면 다 해결된다.
너무 엣지 케이스를 생각하고
먼저 처리해 버리지 말자
.
큰 로직을 먼저
생각하고 최대한 한 묶음으로 처리해서 시간도 단축하고 디버깅 지옥에 빠지지 말자.