20057: 마법사 상어와 토네이도

ewillwin·2023년 7월 14일
0

Problem Solving (BOJ)

목록 보기
124/230

풀이 시간

  • 1h 35m
  • python 내장함수로 2차원 리스트 transpose (-> list(map(list, zip(*A))) 하는거랑 역순으로 루프 돌리는 거 (-> reversed()) 개꿀인듯

구현 방식

  • 일단 direction 리스트를 미리 만들어줌
    -> 토네이도의 방향대로 dx, dy 리스트의 인덱스를 넣은 리스트임
    -> 만든 direction 리스트를 기반으로 for문을 돌면서 한 칸씩 이동함

  • 또한 percent 리스트를 미리 만들어줌
    -> percent0 (왼쪽 방향)을 기준으로 2차원 리스트 전치와 역순 루프 돌리기를 이용해서 (해당 내용은 여기를 참고) 90도씩 회전한 배열들 (아래쪽, 오른쪽, 위쪽 방향)을 모두 구해줌

  • move(x, y, p_idx)
    -> percent[p_idx] 모양으로 for문을 돌면서 local_out_sand를 구해주고 이를 반환해줌

코드

import sys
from collections import deque

#좌 하 우 상
dx = [0, 1, 0, -1]
dy = [-1, 0, 1, 0]

percent0 = [[0, 0, 0.02, 0, 0], [0, 0.1, 0.07, 0.01, 0], [0.05, 'a', 0, 0, 0], [0, 0.1, 0.07, 0.01, 0], [0, 0, 0.02, 0, 0]]
percent1 = list(reversed(list(map(list, zip(*percent0)))))
percent2 = list(reversed(list(map(list, zip(*percent1)))))
percent3 = list(reversed(list(map(list, zip(*percent2)))))
percent = [percent0, percent1, percent2, percent3]

def move(x, y, p_idx):
    origin = float(board[x][y])
    local_out_sand = 0; alpha = []; total_sand = 0
    for i in range(5):
        for j in range(5):
            if 0 <= x-2+i < N and 0 <= y-2+j < N:
                if percent[p_idx][i][j] != 'a' and percent[p_idx][i][j] != 0:
                    board[x-2+i][y-2+j] += int(percent[p_idx][i][j] * origin)
                    total_sand += int(percent[p_idx][i][j] * origin)
                elif percent[p_idx][i][j] == 'a':
                    alpha = [x-2+i, y-2+j, True]
            else:
                if percent[p_idx][i][j] != 'a' and percent[p_idx][i][j] != 0:
                    local_out_sand += int(percent[p_idx][i][j] * origin)
                    total_sand += int(percent[p_idx][i][j] * origin)
                elif percent[p_idx][i][j] == 'a':
                    alpha = [x-2+i, y-2+j, False]
    if alpha[2]:
        board[alpha[0]][alpha[1]] += int(origin) - total_sand
    else:
        local_out_sand += int(origin) - total_sand
  
    return local_out_sand


N = int(sys.stdin.readline()[:-1])
board = []
for n in range(N):
    board.append(list(map(int, sys.stdin.readline()[:-1].split())))

direction = []; mul = 1
for n in range(N*2 - 1):
    for i in range(mul):
        direction.append(n%4)
    if (n+1) % 2 == 0:
        mul += 1

queue = deque([[N//2, N//2]])
out_sand = 0
for idx in range(len(direction) - 1): #한 칸씩 이동
    x, y = queue.popleft()
    d_idx = direction[idx]

    nx = x + dx[d_idx]; ny = y + dy[d_idx]

    out_sand += move(nx, ny, d_idx)

    queue.append([nx, ny])

print(out_sand)

결과

profile
Software Engineer @ LG Electronics

0개의 댓글