Programming/Problem Solving

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

징석 2021. 10. 18. 21:05
728x90

 

https://www.acmicpc.net/problem/21610

 

21610번: 마법사 상어와 비바라기

마법사 상어는 파이어볼, 토네이도, 파이어스톰, 물복사버그 마법을 할 수 있다. 오늘 새로 배운 마법은 비바라기이다. 비바라기를 시전하면 하늘에 비구름을 만들 수 있다. 오늘은 비바라기

www.acmicpc.net

 

항상 그렇듯 삼성 구현 문제는 꼼꼼히 구현만 잘 하면 된다.

없어질 구름과 생긴 구름을 잘 관리해 주면 된다.

 

 

from collections import deque
N, M = map(int, input().split())
dx = [0, 0, -1, -1, -1, 0, 1, 1, 1]
dy = [0, -1, -1, 0, 1, 1, 1, 0, -1]
arr = [list(map(int, input().split())) for _ in range(N)]
clouds = deque([(N-1, 0), (N-1, 1), (N-2, 0), (N-2, 1)])
for _ in range(M):
    d,s = map(int, input().split())
    next_clouds = deque()
    while clouds:
        x,y = clouds.popleft()
        temp_s = s
        # 1.모든 구름이 di 방향으로 si칸 이동한다.
        while temp_s:
            temp_s -= 1
            x = x + dx[d]
            y = y + dy[d]
            if x < 0: x=N-1
            elif x >= N: x = 0
            if y < 0: y = N-1
            elif y >= N: y = 0
        next_clouds.append((x,y))
    # 2. 각 구름에서 비가 내려 구름이 있는 칸의 바구니에 저장된 물의 양 1 증가
    not_clouds = set()
    while next_clouds: # 3. 구름이 모두 사라짐
        x,y = next_clouds.popleft()
        not_clouds.add((x,y))
        arr[x][y] += 1
    # 4. 대각선 물 증가
    for x,y in not_clouds:
        cnt = 0
        for i in range(2, 9, 2):
            xx = x + dx[i]
            yy = y + dy[i]
            if 0<=xx<N and 0<=yy<N and arr[xx][yy] >0:
                cnt += 1
        arr[x][y] += cnt
    # 5. 바구니에 저장된 물의 양이 2 이상인 모든 칸에 구름이 생기고, 물의 양이 2 줄어든다
    for i in range(N):
        for j in range(N):
            if arr[i][j] > 1 and (i,j) not in not_clouds:
                clouds.append((i,j))
                arr[i][j] -= 2

res = 0
for i in range(N):
    for j in range(N):
        res += arr[i][j]
print(res)