20056 - 마법사 상어와 파이어볼

1 minute read

1. 문제

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

2. 소스코드

'''
NxN 격자
파이어볼 M개

'''
from collections import defaultdict

# N : 격자, M : 파이어볼, K : 실행 횟수
N,M,K = map(int,input().split()) 

# r,c : 위치 ,m : 질량,s : 속력, d : 방향

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

for i in range(len(f_balls)):
    r,c,m,s,d = f_balls[i]
    f_balls[i] = [r-1,c-1,m,s,d]
# 파이어볼의 방향은 어떤 칸과 인접한 8개의 칸의 방향을 의미하며, 정수로는 다음과 같다.
dr = [-1,-1,0,1,1,1,0,-1]
dc = [0,1,1,1,0,-1,-1,-1]

pos = defaultdict(list)
# 1.모든 파이어볼이 자신의 방향 di로 속력 si칸 만큼 이동한다.
def move():
    for i in range(len(f_balls)):
        r,c,m,s,d = f_balls[i]

        nr = r + dr[d]*s + N*s
        nc = c + dc[d]*s + N*s

        nr %= N
        nc %= N
        f_balls[i] = [nr,nc,m,s,d]

# 2.이동이 모두 끝난 뒤, 2개 이상의 파이어볼이 있는 칸에서는 다음과 같은 일이 일어난다.

def get_balls():
    global pos
    pos = defaultdict(list)

    for i in range(len(f_balls)):
        r,c,_,_,_ = f_balls[i]
        # rc = ",".join(map(str,[r,c]) 
        pos[(r,c)].append(f_balls[i]) # dictionary의 key 값으로 tuple을 전달할 수 있음

def process_balls():
    global f_balls
    tmp = []
    for key in pos.keys():
        if len(pos[key]) >= 2:
            tmp_r,tmp_c = key
            tmp_m,tmp_s,tmp_d = 0,0,[]
            tmp_balls = pos[key]
            for _,_,m,s,d in tmp_balls:
                tmp_m += m
                tmp_s += s
                tmp_d.append(d%2)
            # 2-3-1. 질량 : sum(파이어볼질량)/5
            tmp_m //= 5
            # 2-3-2. 속력 : sum(파이어볼속력)/합쳐진 파이어볼 개수
            tmp_s //=len(tmp_balls)
            # 2-3-3. 방향 : 합쳐지는 방향 모두 홀수 or 짝수 -> 0,2,4,6 else 1,3,5,7
            tmp_d = set(tmp_d)
            tmp_d = [0,2,4,6] if len(tmp_d) == 1 else [1,3,5,7]
            # 2-4. 질량 0인 파이어볼 소멸 <- 2-3-1에서 반올림해야되는지 확인
            if tmp_m == 0:
                continue
            for d in tmp_d:
                tmp.append([tmp_r,tmp_c,tmp_m,tmp_s,d])
        elif len(pos[key]) == 1:
            tmp += pos[key]
    f_balls = tmp

# 3.마법사 상어가 이동을 K번 명령한 후, 남아있는 파이어볼 질량의 합을 출력한다.
def get_answer():
    answer = 0
    for _,_,m,_,_ in f_balls:
        answer += m
    print(answer)

# main
for _ in range(K):
    move()
    get_balls()
    process_balls()

get_answer()

3. 코드리뷰

시뮬레이션 잘하여 풀이

4. 개선사항

문제 꼼꼼하게 읽기

Leave a comment