[BOJ 21610] 마법사 상어와 비바라기(Python)

박현우·2021년 5월 21일
0

BOJ

목록 보기
72/87

문제

비바라기


문제 해설

상어 문제는 제한사항을 꼼꼼히 읽지 않으면 나중에 어마어마한 리스크가 되어 돌아오는 것 같습니다.

구현 내용을 나열하자면

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)

0개의 댓글