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

ewillwin·2023년 7월 14일
0

Problem Solving (BOJ)

목록 보기
122/230

풀이 시간

  • 1h 15m
  • "격자의 행과 열은 1번부터 N번까지 번호가 매겨져 있고, 1번 행은 N번과 연결되어 있고, 1번 열은 N번 열과 연결되어 있다."라는 말이 잘 이해가 안갔는데, 약간 차원 이동처럼 1번 행에서 위로 올라가면 N번 행이고 1번 열에서 왼쪽으로 이동하면 N번 열이다 이런 소리인듯

구현 방식

  • 문제에 나온대로 구현하면 되는 문제
  • 3차원 리스트로 처리해주었다.
    • 파이어볼이 없는 칸은 0
    • 파이어볼이 있는 칸은 deque([[m, s, d, check], [m, s, d, check], ...]) 이런식으로 들어감
    • check은 이동을 수행한 파이어볼의 경우 1이고 이동을 아직 수행하지 않은 파이어볼의 경우 0이다
  • K만큼 for문을 돌면서 이동하는 경우와 이동후 처리하는 부분을 따로 처리해줌

  • 이동
    • board가 0이 아니라면 파이어볼이 있는 경우이므로 해당 칸의 파이어볼의 개수만큼 for문을 돌며 모두 이동시켜준다
    • popleft를 해서 현재 위치에서 파이어볼을 빼고 이동후 위치로 이동시켜준다. 만약 여기서 check이 1이라면 이미 이동을 수행했던 파이어볼이기 때문에 다시 appendleft 해줘야함

  • 이동 후 처리
    • length가 2 이상이라면 파이어볼을 합치고 4개로 나누는 작업을 해줘야한다
    • 해당 칸의 파이어볼들을 순회하며 tm, ts, o_cnt, e_cnt를 구해주고, 그에 맞게 board[x][y]에 나누어진 4개의 파이어볼들을 넣어준다. 만약 tm이 0이라면 파이어볼은 소멸되므로 0을 넣어줌
    • 추가적으로, board[x][y]가 0이 아니고 length가 1이라면 check를 다시 0으로 바꿔줘야함 (그래야 다음 차례에서 이동을 수행함)

코드

import sys
from collections import deque

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

N, M, K = map(int, sys.stdin.readline()[:-1].split())
board = [[0] * N for _ in range(N)]
for m in range(M):
    r, c, m, s, d = map(int, sys.stdin.readline()[:-1].split())
    board[r-1][c-1] = deque([[m, s, d, 0]])

for _ in range(K):
    # 이동
    for x in range(N):
        for y in range(N):
            if board[x][y] != 0:
                for l in range(len(board[x][y])):
                    m, s, d, check = board[x][y].popleft()
                    if check == 0:
                        if not board[x][y]:
                            board[x][y] = 0
                        nx = (x + s*dx[d])%N; ny = (y + s*dy[d])%N
                        if board[nx][ny] == 0:
                            board[nx][ny] = deque([[m, s, d, 1]])
                        else:
                            board[nx][ny].append([m, s, d, 1])
                    else:
                        board[x][y].appendleft([m, s, d, check])

    # 이동 후 처리
    for x in range(N):
        for y in range(N):
            if board[x][y] != 0:
                length = len(board[x][y])
                if length >= 2:
                    tm = 0; ts = 0; o_cnt = 0; e_cnt = 0
                    for l in range(length):
                        m, s, d, check = board[x][y][l]
                        tm += m; ts += s
                        if d % 2 == 0:
                            e_cnt += 1
                        else:
                            o_cnt += 1
                    tm //= 5; ts //= length

                    if tm != 0:
                        if e_cnt == length or o_cnt == length:
                            board[x][y] = deque([[tm, ts, 0, 0], [tm, ts, 2, 0], [tm, ts, 4, 0], [tm, ts, 6, 0]])
                        else:
                            board[x][y] = deque([[tm, ts, 1, 0], [tm, ts, 3, 0], [tm, ts, 5, 0], [tm, ts, 7, 0]])
                    else:
                        board[x][y] = 0
                else:
                    board[x][y][0][3] = 0

total_m = 0
for i in range(N):
    for j in range(N):
        if board[i][j] != 0:
            for b in board[i][j]:
                total_m += b[0]
print(total_m)

결과

profile
💼 Software Engineer @ LG Electronics | 🎓 SungKyunKwan Univ. CSE

0개의 댓글