[백준 삼성기출 O] 마법사 상어와 파이어볼(python)

이진규·2022년 10월 6일
1

백준(PYTHON)

목록 보기
98/115

문제

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

나의 코드

"""

"""

N, M, K = map(int, input().split()) # N : 격자판 크기, M : 파이어볼 개수, K : 명령 횟수
pan = [ [[] for _ in range(N)] for _ in range(N) ] # N * N 격자판 크기
f_ball = [ list(map(int, input().split())) for _ in range(M) ] # 파이어볼 정보 : r, c, m, s, d - 행, 열, 질량, 속력, 방향

for i in range(len(f_ball)): # 파이어볼 배치
    r, c, m, s, d = f_ball[i]
    pan[r-1][c-1].append((m, s, d))


def odd_even(arr): # 배열의 모든 수가 홀수 또는 짝수인지 판별
    cnt = len(arr)
    odd, even = 0, 0
    for p in arr:
        if p % 2 == 0:
            even += 1
        else:
            odd += 1

    if odd == cnt or even == cnt:
        return True
    return False

dx = [-1, -1, 0, 1, 1, 1, 0, -1]
dy = [0, 1, 1, 1, 0, -1, -1, -1]
def move():

    move_f_ball = []
    for i in range(N): # 파이어볼의 이동 구현
        for j in range(N):
            if pan[i][j]:
                while pan[i][j]:
                    m, s, d = pan[i][j].pop(0)
                    x, y = i, j
                    mx = x + (dx[d] * s)
                    my = y + (dy[d] * s)

                    if not (0 <= mx < N and 0 <= my < N):
                        mx = mx % N
                        my = my % N

                    move_f_ball.append((mx, my, m, s, d))

    for mx, my, m, s, d in move_f_ball: # 이동한 파이어 볼 배치
        pan[mx][my].append((m, s, d))


    for i in range(N): # 파이어볼이 겹치는 경우 처리
        for j in range(N):
            if len(pan[i][j]) >= 2:
                pan_cnt = len(pan[i][j])
                sum_m, sum_s, sum_d = 0, 0, []
                while pan[i][j]:
                    m, s, d = pan[i][j].pop(0)
                    sum_m += m
                    sum_s += s
                    sum_d.append(d)
                sum_m, sum_s = sum_m//5, sum_s//pan_cnt

                if odd_even(sum_d):
                    sum_d = [0, 2, 4, 6]
                else:
                    sum_d = [1, 3, 5, 7]

                if sum_m == 0:
                    continue # ★하 이거 break 썼다가 개 고생함 - 여기서 그만 두는게 아니라 계속 진행해야지
                for k in range(4):
                    pan[i][j].append((sum_m, sum_s, sum_d[k]))

for _ in range(K):
    move()

answer = 0
for i in range(N): # 남아 있는 파이어볼의 질량 세기
    for j in range(N):
        if pan[i][j]:
            while pan[i][j]:
                m, s, d = pan[i][j].pop(0)
                answer += m

print(answer)
    

설명

구현 문제 - 설명대로 풀면 쉽게 풀 수 있다.
다만 continue 이 부분 조심..

참고 자료

profile
항상 궁금해하고 공부하고 기록하자.

0개의 댓글