chldkato

백준 20057 마법사 상어와 토네이도 (파이썬) 본문

백준

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

chldkato 2021. 2. 20. 00:34

www.acmicpc.net/problem/20057

 

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

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

www.acmicpc.net

1. 지도의 중앙인 n // 2 부터 반복문을 시작한다. x, y 좌표가 0이 되면 반복문을 종료한다.

2. 필요한 변수를 만들어준다. i는 이동할 방향을 정해준다.

3. 문제에 조건에 맞게 이동할 모래의 양들을 구해놓는다.

4. 모래가 이동할 좌표를 구한다. 각각 (i + 3) % 4, (i + 1) % 4로 모래가 위치할 방향을 구할 수 있다.

5. storm 함수를 통해, 좌표가 지도 범위 안에 있으면 지도의 모래양을 갱신하고 범위 밖이면 ans에 모래를 더한다

6. 토네이도가 이동하면서 방향을 바꿔야 하는지를 구현해야한다.

   cnt로 이동한 횟수를 세고 방향을 바꿀지 결정하는 turn과 일치하면 i를 다음 방향으로 바꿔준다

   move는 현재 방향에서 몇칸 이동한 후 방향을 바꿀지 결정해준다.

   이렇게 구현하면 토네이도처럼 좌표가 이동한다.

7. 반복문을 나오면 ans를 출력한다.

import sys

def storm(x, y, sand):
    global ans
    if 0 <= x < n and 0 <= y < n:
        a[x][y] += sand
    else:
        ans += sand

input = sys.stdin.readline
dx = [0, 1, 0, -1]
dy = [-1, 0, 1, 0]

n = int(input())
a = [list(map(int, input().split())) for _ in range(n)]
x, y = n // 2, n // 2

i, cnt, ans, move, turn = 0, 0, 0, 0, 1
while True:
    nx = x + dx[i]
    ny = y + dy[i]
    if a[nx][ny]:
        _1 = int(a[nx][ny] * 0.01)
        _2 = int(a[nx][ny] * 0.02)
        _7 = int(a[nx][ny] * 0.07)
        _5 = int(a[nx][ny] * 0.05)
        _10 = int(a[nx][ny] * 0.1)
        rem = a[nx][ny] - 2 * (_1 + _2 + _7 + _10) - _5

        _1x_u, _1y_u = x + dx[(i + 3) % 4], y + dy[(i + 3) % 4]
        _1x_d, _1y_d = x + dx[(i + 1) % 4], y + dy[(i + 1) % 4]
        _2x_u, _2y_u = nx + 2 * dx[(i + 3) % 4], ny + 2 * dy[(i + 3) % 4]
        _2x_d, _2y_d = nx + 2 * dx[(i + 1) % 4], ny + 2 * dy[(i + 1) % 4]
        _7x_u, _7y_u = nx + dx[(i + 3) % 4], ny + dy[(i + 3) % 4]
        _7x_d, _7y_d = nx + dx[(i + 1) % 4], ny + dy[(i + 1) % 4]

        tx, ty = nx + dx[i], ny + dy[i]
        _10x_u, _10y_u = tx + dx[(i + 3) % 4], ty + dy[(i + 3) % 4]
        _10x_d, _10y_d = tx + dx[(i + 1) % 4], ty + dy[(i + 1) % 4]
        _5x, _5y = tx + dx[i], ty + dy[i]

        storm(tx, ty, rem)
        storm(_1x_u, _1y_u, _1)
        storm(_1x_d, _1y_d, _1)
        storm(_2x_u, _2y_u, _2)
        storm(_2x_d, _2y_d, _2)
        storm(_7x_u, _7y_u, _7)
        storm(_7x_d, _7y_d, _7)
        storm(_10x_u, _10y_u, _10)
        storm(_10x_d, _10y_d, _10)
        storm(_5x, _5y, _5)

    if x == 0 and y == 0:
        break

    a[nx][ny] = 0
    x, y = nx, ny
    cnt += 1
    if cnt == turn:
        i = (i + 1) % 4
        cnt = 0
        move += 1
        if move % 2 == 0:
            turn += 1
            move = 0

print(ans)

Comments