Koala - 10기/코딩테스트 준비 스터디

[백준/Python] 21610 마법사 상어와 비바라기

긍살:D 2023. 3. 26. 15:57

문제링크

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

 

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

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

www.acmicpc.net


코드

import sys
input = sys.stdin.readline
n,m = map(int,input().split())
graph = [list(map(int,input().split())) for _ in range(n)]
cloud = [[n-1,0],[n-1,1],[n-2,0],[n-2,1]] #초기 구름의 위치
direction = [(0,0),(0,-1),(-1,-1),(-1,0),(-1,1),(0,1),(1,1),(1,0),(1,-1)] # ←, ↖, ↑, ↗, →, ↘, ↓, ↙
cross_check = [(-1,-1),(-1,1),(1,1),(1,-1)]#대각선방향 4종류

def move(d,s):
    for i in range(len(cloud)):
        cloud[i][0] = (cloud[i][0]+(direction[d][0]*s))%n
        cloud[i][1] = (cloud[i][1]+(direction[d][1]*s))%n

def rain():
    for x,y in cloud: # 구름이 있는 칸의 물의 양 1씩 증가
        graph[x][y] +=1
    for x,y in cloud: #대각선 4방향 체크하면서 물의 양이 0이 아니면 1씩 증가
        for i in range(4):
            nx = x+cross_check[i][0]
            ny = y+cross_check[i][1]
            if nx<0 or ny<0 or nx>=n or ny>=n:continue# 범위 벗어날 경우 처리
            if graph[nx][ny] !=0:graph[x][y]+=1

def make_cloud(): 
    vis = [[0]*n for _ in range(n)]#vis로 기존 구름의 위치를 기록
    for i,j in cloud:
        vis[i][j] = 1
    new_cloud = [] #새로운 구름의 위치
    for i in range(n):
        for j in range(n):
            if not vis[i][j] and graph[i][j]>=2:# in연산자를 이용하면 시간초과
                graph[i][j]-=2
                new_cloud.append([i,j])
    return new_cloud

for _ in range(m):
    d,s = map(int,input().split())
    move(d,s)
    rain()
    cloud = make_cloud()

result = 0
for i in range(n):
    result += sum(graph[i])
print(result)

문제풀이

시뮬레이션 문제이다. 주어진 조건을 함수로 나누어 구현하였다.

1. 모든 구름이 di 방향으로 si칸 이동한다.

2. 구름이 있는 칸의 바구니에 저장된 물의 양이 1 증가한다. 그리고 대각선의 물이 있는 바구니 수만큼 물의 양이 증가한다.

3. 이전에 구름이 아니였던 칸 중에서 물의 양이 2이상인 칸에 구름이 생긴다.

 

1.move(d,s) -> d방향으로 s만큼 이동동한다. 리스트의 길이가 넘어갈 수 있으므로 %연산자를 이용하여 이동시켰다.

2.rain() -> 현재 구름이 있는 모든칸의 물의 양을 1 증가 시켜주고, 대각선 4방향을 체크한 후 물의 양이 0이 아니면 현재 칸의 물의 양을 1씩 증가시켜줬다.

3.make_cloud() -> vis 2차원 리스트를 선언하여 현재 구름의 위치를 기록해준다. (vis[i][j]=1)

그리고 물의 양이 2이상이고 vis가 0인 모든 칸을 구름이 위치한 칸으로 저장한 후, 물의 양을 2씩 줄여준다.