본문 바로가기

알고리즘/백준

[백준] 20056번 : 마법사 상어와 파이어볼

728x90

20056번: 마법사 상어와 파이어볼

 

20056번: 마법사 상어와 파이어볼

첫째 줄에 N, M, K가 주어진다. 둘째 줄부터 M개의 줄에 파이어볼의 정보가 한 줄에 하나씩 주어진다. 파이어볼의 정보는 다섯 정수 ri, ci, mi, si, di로 이루어져 있다. 서로 다른 두 파이어볼의 위치

www.acmicpc.net

🤔 문제분석

문제의 포인트는 1번행과 N번행이 연결되어있고, N번열과 1번열이 연결되어있는 상태를 어떻게 구현할 것인가가 이 문제의 포인트 입니다. chage_dir 함수를 만들었고 해당 함수는 음수가 되든 범위가 넘어가든 상황을 나머지 연산을 활용하여 처리하였습니다. 파이어볼이 여러개 모여있는곳을 딕셔너리를 활용하여 딕셔너리에 리스트를 받고 리스트가 2보다 클경우 파이어볼을 분산시킵니다.

💻 코드

import sys
from collections import defaultdict
input = sys.stdin.readline

N, M, K = map(int, input().split())
moves = [(-1, 0), (-1, 1), (0, 1), (1, 1), (1, 0), (1, -1), (0, -1), (-1, -1)]
direction = [(0, 2, 4, 6), (1, 3, 5, 7)]

def chage_dir(y, x):
    y = (y + N) % N
    x = (x + N) % N
    return y, x
        
fire_ball = []
for _ in range(M):
    # 위치, 질량, 속도, 방향
    r, c, m, s, d = map(int, input().split())
    fire_ball.append([r-1, c-1, m, s, d])

def move_fire_ball(fire_ball):
    new_fire_ball = []
    table = defaultdict(list)
    
    for y, x, m, s, d in fire_ball:
        y, x = chage_dir(y + moves[d][0]*s, x + moves[d][1]*s)
        table[(y, x)].append((m, s, d))
        
    for key in table.keys():
        y, x = key
        if len(table[key]) >= 2:
            sum_m = 0
            sum_s = 0
            odd = 0
            even = 0
            for nm, ns, nd in table[key]:
                sum_m += nm
                sum_s += ns
                if nd % 2 == 0:
                    even += 1
                else:
                    odd += 1
                    
            new_m = sum_m // 5
            new_s = sum_s // len(table[key])
            if new_m > 0:
                if even == 0 or odd == 0:
                    new_d = 0
                else:
                    new_d = 1
                for i in range(4):
                    new_fire_ball.append([y, x, new_m, new_s, direction[new_d][i]])

        else:
            m, s, d = table[key][0]
            new_fire_ball.append([y, x, m, s, d])
    
    return new_fire_ball
            
for _ in range(K):
    fire_ball = move_fire_ball(fire_ball)
    
print(sum(m[2] for m in fire_ball))

🎯 피드백 및 개선사항

범위를 체크하는 로직이 이문제의 핵심이었습니다.

728x90