코딩테스트/구현

마법사 상어와 비바라기

수타. 2023. 8. 11. 16:07

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

 

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

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

www.acmicpc.net

문제요약:

n*n 바구니의 물의양이 주어지고 

  1. 모든 구름이 di 방향으로 si칸 이동한다.
  2. 각 구름에서 비가 내려 구름이 있는 칸의 바구니에 저장된 물의 양이 1 증가한다.
  3. 구름이 모두 사라진다.
  4. 2에서 물이 증가한 칸 (r, c)에 물복사버그 마법을 시전한다. 물복사버그 마법을 사용하면, 대각선 방향으로 거리가 1인 칸에 물이 있는 바구니의 수만큼 (r, c)에 있는 바구니의 물이 양이 증가한다.
    • 이때는 이동과 다르게 경계를 넘어가는 칸은 대각선 방향으로 거리가 1인 칸이 아니다.
    • 예를 들어, (N, 2)에서 인접한 대각선 칸은 (N-1, 1), (N-1, 3)이고, (N, N)에서 인접한 대각선 칸은 (N-1, N-1)뿐이다.
  5. 바구니에 저장된 물의 양이 2 이상인 모든 칸에 구름이 생기고, 물의 양이 2 줄어든다. 이때 구름이 생기는 칸은 3에서 구름이 사라진 칸이 아니어야 한다.

다음과 같은 기준에 따라 물의양이 이동할 때, 이동이 모두 끝난 후 바구니에 들어있는 물의 양의 합을 출력하라

 

소요시간:

35분

 

난이도 :

골드5

 

제출횟수:

1번

 

코딩:

import sys
input = sys.stdin.readline
        
n,m = map(int,input().split())

arr = [list(map(int,input().split())) for _ in range(n)]

ds = [list(map(int,input().split())) for _ in range(m)]
cloud = [[-1,0],[-1,1],[-2,0],[-2,1]]

dy = [0,-1,-1,-1,0,1,1,1]
dx = [-1,-1,0,1,1,1,0,-1]

def fix(x):
    while x<0:
        x+=n
    while x>=n:
        x-=n
    return x
    
for d,s in ds:
    water = []
    #모든 구름이 이동한다
    for y,x in cloud:
        ny = fix(y+s*dy[d-1])
        nx = fix(x+s*dx[d-1])
        #저장된물 증가
        arr[ny][nx] +=1
        #물이 증가한 칸 저장
        water.append([ny,nx])
        
    #구름 초기화   
    cloud = []
    #대각선에 물 확인후 증가
    for y,x in water:
        for i in range(1,8,2):
            ny = y+dy[i]
            nx = x+dx[i]
            if 0<=ny<n and 0<=nx<n:
                if arr[ny][nx]:
                    arr[y][x]+=1
    #내부 판단을 위해 set으로 변경                
    water = set([n*y+x for y,x in water])
    for y in range(n):
        for x in range(n):
            if n*y+x not in water and arr[y][x] >=2:
                cloud.append([y,x])
                arr[y][x]-=2
                
print(sum([i for j in arr for i in j]))

차근차근 문제에서 주어진 규칙을 따라가면 되는 구현 문제였습니다. 구름이 이동할때 벽에 끝에 다다르면 맞은편으로 넘어가기 때문에 fix함수를 통해 이를 바꿔주었고, 마지막에 구름이 있었던 곳 제외하고 다시 구름을 설정할때 비교의 편의를 위해 set함수를 통해 1차원으로 바꿔주어 비교를 했습니다.