상어 문제는 제한사항을 꼼꼼히 읽지 않으면 나중에 어마어마한 리스크가 되어 돌아오는 것 같습니다.
구현 내용을 나열하자면
1. 구름 이동
이 부분은 이동과 동시에 비 내리기를 같이 구현했습니다. 여기서 맵을 벗어나면 핸들링이 필요하기 때문에 그 부분을 조심하고 이동한 구름의 좌표가 필요하기 때문에 큐에 담아줬습니다.
추후에 이동한 구름 자리에 구름이 생기면 안되므로 visited 라는 방문 체크 리스트를 만들어 갱신했습니다.
2. 물 복사
구름이 사라진 것과 물이 복사 되는 것을 같이 구현했고, 큐에 넣었던 좌표를 하나씩 꺼내 대각선만 체크합니다.
범위 안이면서 물이 존재한다면 현재 자리에 물을 +1 해주면 됩니다.
3. 구름 생성
전체 바구니를 검사해 구름을 생성해야 하기 때문에 아까 만든 visited와 물이 2이상인 지점을 다시 큐에 넣었습니다.
4. 모든 물의 양 구하기
N*N
바구니를 모두 더해 답을 출력합니다.
import sys
from collections import deque
input = sys.stdin.readline
n, m = map(int, input().split())
graph = [list(map(int, input().split())) for _ in range(n)]
dir_move = [list(map(int, input().split())) for _ in range(m)]
dx = 0, -1, -1, -1, 0, 1, 1, 1
dy = -1, -1, 0, 1, 1, 1, 0, -1
cloud = [(n - 1, 0), (n - 1, 1), (n - 2, 0), (n - 2, 1)]
cloud = deque(cloud)
def move_rain(dir, dist):
global n
size = len(cloud)
for _ in range(size):
x, y = cloud.popleft()
nx = (x + dx[dir] * dist) % n
ny = (y + dy[dir] * dist) % n
if 0 > nx:
nx += n
if 0 > ny:
ny += n
cloud.append((nx, ny))
# 구름이 사라진 자리를 표시
visited[nx][ny] = True
graph[nx][ny] += 1
def dup():
while cloud:
# 대각선 검사
x, y = cloud.popleft()
for i in range(1, 8, 2):
nx = x + dx[i]
ny = y + dy[i]
if 0 <= nx < n and 0 <= ny < n and graph[nx][ny] > 0:
graph[x][y] += 1
for dir, dist in dir_move:
visited = [[False] * n for _ in range(n)]
# 1. 구름 이동 후 비 내리기
move_rain(dir - 1, dist)
# 2. 물 복사
dup()
# 3. 구름 생성
for i in range(n):
for j in range(n):
if graph[i][j] >= 2 and not visited[i][j]:
cloud.append((i, j))
graph[i][j] -= 2
answer = 0
for i in range(n):
for j in range(n):
answer += graph[i][j]
print(answer)