Algorithm/Implementation

[백준] 20057 마법사 상어와 토네이도 (Python 파이썬)

안드선생 2021. 10. 24. 08:38
반응형

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

 

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

마법사 상어가 토네이도를 배웠고, 오늘은 토네이도를 크기가 N×N인 격자로 나누어진 모래밭에서 연습하려고 한다. 위치 (r, c)는 격자의 r행 c열을 의미하고, A[r][c]는 (r, c)에 있는 모래의 양을

www.acmicpc.net

문제 설명

문제의 자세한 설명은 위 링크를 참조하시길 바랍니다.

이 문제는 구현 시뮬레이션 문제로, 문제에서 요구하는 사항이 꽤 많고 상세합니다. 

빠짐없이 체크하여 어떻게 구현해야 할지 구상한 후에 구현해야 하는 문제입니다.


풀이 과정

from collections import deque

n = int(input())
graph = []
graphIdx = deque()
dx = [0, 1, 0, -1]
dy = [-1, 0, 1, 0]
d_left = [(-1, 0, 0.01), (1, 0, 0.01), (-1, -1, 0.07), (1, -1, 0.07), (-2, -1, 0.02), (2, -1, 0.02), (-1, -2, 0.10),
          (1, -2, 0.10), (0, -3, 0.05), (0, -2, 0)]
d_right = [(-1, 0, 0.01), (1, 0, 0.01), (-1, 1, 0.07), (1, 1, 0.07), (-2, 1, 0.02), (2, 1, 0.02), (-1, 2, 0.10),
           (1, 2, 0.10), (0, 3, 0.05), (0, 2, 0)]
d_up = [(0, -1, 0.01), (0, 1, 0.01), (-1, -1, 0.07), (-1, 1, 0.07), (-1, -2, 0.02), (-1, 2, 0.02), (-2, -1, 0.10),
        (-2, 1, 0.10), (-3, 0, 0.05), (-2, 0, 0)]
d_down = [(0, -1, 0.01), (0, 1, 0.01), (1, -1, 0.07), (1, 1, 0.07), (1, -2, 0.02), (1, 2, 0.02), (2, -1, 0.10),
          (2, 1, 0.10), (3, 0, 0.05), (2, 0, 0)]

for i in range(n):
    graph.append(list(map(int, input().split())))


def indexing():
    x, y = n // 2, n // 2
    depth = 0

    while True:
        for i in range(4):
            if i % 2 == 0:
                depth += 1
            for j in range(depth):
                graphIdx.append((x, y, i))
                if x == 0 and y == 0:
                    return
                x += dx[i]
                y += dy[i]


def tornado(x, y, d):
    global answer

    nx = x + dx[d]
    ny = y + dy[d]
    tmp = graph[nx][ny]
    graph[nx][ny] = 0

    outSand = 0
    total = 0

    if d == 0:
        dir = d_left
    elif d == 1:
        dir = d_down
    elif d == 2:
        dir = d_right
    else:
        dir = d_up

    for i in range(9):
        ddx = dir[i][0]
        ddy = dir[i][1]
        ratio = dir[i][2]

        if x + ddx < 0 or x + ddx >= n or y + ddy < 0 or y + ddy >= n:
            outSand += int(tmp * ratio)
            answer += int(tmp * ratio)
            continue
        else:
            graph[x + ddx][y + ddy] += int(tmp * ratio)
            total += int(tmp * ratio)

    if x + dir[9][0] < 0 or x + dir[9][0] >= n or y + dir[9][1] < 0 or y + dir[9][1] >= n:
        answer += (tmp - total - outSand)
    else:
        graph[x + dir[9][0]][y + dir[9][1]] += (tmp - total - outSand)


answer = 0
indexing()
while graphIdx:
    x, y, d = graphIdx.popleft()
    if x == 0 and y == 0:
        break
    tornado(x, y, d)

print(answer)

https://github.com/HongEunho

전체 문제 & 코드는 위의 깃에 정리되어 있습니다.

팔로우 & 맞팔은 환영입니다 !

반응형