[백준] 21610번: 마법사 상어와 비바라기

CodingJoker·2024년 6월 25일

백준

목록 보기
11/83

문제

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

분석

문제를 잘 읽고, 손으로 어떻게 동작하는지 그려봐서 이해를 하고 난 뒤 코딩을 하는 것이 좋다.
문제에서는 3. 구름이 사라진다가 먼저 나왔지만, 뒤에 과정에서 이 구름의 위치가 필요하다.
따라서 이런 것들의 순서조정은 코드에 적용하기 편하게 바꾸면 된다.

python3로는 통과하지 못하고 pypy3로 통과했다.
cloud들의 위치에 해당하는 지 확인하는 과정에서 오래걸리는 것 같다.

코드

해결언어 : Python

import sys
input = sys.stdin.readline

n, m = map(int, input().split())
grid = [
    list(map(int, input().split()))
    for _ in range(n)
]
dx = [0,-1,-1,-1,0,1,1,1]
dy = [-1,-1,0,1,1,1,0,-1]
cloud_pos = [(n-1, 0), (n-1, 1), (n-2, 0), (n-2, 1)]

def moveCloud(d, s):
    for i in range(len(cloud_pos)):
        x, y = cloud_pos[i]
        nx, ny = (x + dx[d]*s)%n, (y + dy[d]*s)%n
        cloud_pos[i] = (nx, ny)

def rain():
    for x, y in cloud_pos:
        grid[x][y] += 1

def in_range(x, y):
    return 0<=x<n and 0<=y<n

def copyWaterMagic():
    dxs = [1,1,-1,-1]
    dys = [1,-1,1,-1]
    for x, y in cloud_pos:
        cnt = 0
        for dx, dy in zip(dxs, dys):
            nx, ny = x + dx, y + dy
            if in_range(nx, ny) and grid[nx][ny]:
                cnt += 1
        grid[x][y] += cnt

def genNewCloud():
    new_cloud_pos = []
    for i in range(n):
        for j in range(n):
            if grid[i][j] >= 2 and (i, j) not in cloud_pos:
                grid[i][j] -= 2
                new_cloud_pos.append((i, j))
    return new_cloud_pos

for _ in range(m):
    d, s = map(int, input().split())
    d -= 1
    moveCloud(d, s)
    rain()
    copyWaterMagic()
    cloud_pos = genNewCloud()[:]
    
water = 0
for i in range(n):
    water += sum(grid[i])
print(water)

끝으로..

구현 문제로 요구사항을 분석하여 기능별로 캡슐화하는 연습을 했다.
복잡해 보이는 문제도 이렇게 작게 쪼개고, 각 함수가 정확하게 동작하는지 체크하고 넘어가면 실수를 줄이는 좋은 방법인 것 같다.

profile
어제보다 지식 1g 쌓기

0개의 댓글