코딩하는 덕구 🐶

140. [삼성기출36]Python 백준 20057 마법사 상어와 토네이도 본문

알고리즘 문제 풀이

140. [삼성기출36]Python 백준 20057 마법사 상어와 토네이도

코딩하는 덕구 🐶 2023. 8. 16. 23:02
728x90
반응형

안녕하세요 코딩하는 덕구입니다.

파이썬 백준 20057 마법사 상어와 토네이도 입니다.

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

 

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

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

www.acmicpc.net

 

문제 접근

1. 토네이도를 좌, 하, 우, 상 순서대로 이동시켜야 하므로 모든 방향으 토네이도를 구현해야 됩니다.

이때 토네이도 하나만 구현하면 나머지 토네이도는 단순한 계산으로 쉽게 구현 가능합니다.

예를들어 왼쪽 토네이도를 구현했다면 오른쪽 토네이도는 x, y에서 y 축만 대칭시켜주면 되므로 y대신 -y를 집어넣으면 됩니다.

 

2. a를 구해야 되는데 a는 55프로가 아닌 이동하지 못한 남은 모래의 양 이므로

모래가 이동 할 때마다 더해서 변수에 저장하고 원래의 모래를 빼서 계산해주면 됩니다.

 

Python 정답 코드

백준 20057 마법사 상어와 토네이도 파이썬 코드입니다. 설명은 아래에 있습니다.

N = int(input())
board = [list(map(int, input().split())) for _ in range(N)]
move_left = [(-1, 1, 0.01), (-1, 0, 0.07), (-2, 0, 0.02), (-1, -1, 0.1),
             (0, -2, 0.05), (1, -1, 0.1), (1, 0, 0.07), (1, 1, 0.01),
             (2, 0, 0.02), (0, -1, 0)]

move_right = [(x, -y, z) for x, y, z in move_left]
move_up = [(y, x, z) for x, y, z in move_left]
move_down = [(-y, x, z) for x, y, z in move_left]

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


def move(x, y, d):
    if d == 0:
        move_list = move_left
    if d == 1:
        move_list = move_down
    if d == 2:
        move_list = move_right
    if d == 3:
        move_list = move_up

    out = 0
    total = board[x][y]
    for m in move_list:
        r, c, p = m
        nx, ny = x + r, y + c
        if 0 <= nx < N and 0 <= ny < N:
            if p != 0:
                board[nx][ny] += int(board[x][y] * p)
                total -= int(board[x][y] * p)
            else:
                board[nx][ny] += total
        else:
            if p != 0:
                out += int(board[x][y] * p)
                total -= int(board[x][y] * p)
            else:
                out += total

    board[x][y] = 0
    return out

def tornado():
    x, y = N//2, N//2
    d = 0
    out = 0
    change_d = 0
    length = 1
    while True:
        if change_d == 2:
            change_d = 0
            length += 1
        for i in range(length):
            x, y = dx[d] + x, dy[d] + y

            if [x, y] == [0, -1]:
                return out
            out += move(x, y, d)

        d = (d + 1) % 4
        change_d += 1
    return

print(tornado())

 

Python 코드 설명

먼저 모래가 있는 2차원 리스트 board를 선언하고

왼쪽으로 이동하는 토네이도를 선언합니다.

N = int(input())
board = [list(map(int, input().split())) for _ in range(N)]
dx = [0, 1, 0, -1]
dy = [-1, 0, 1, 0]
move_left = [(-1, 1, 0.01), (-1, 0, 0.07), (-2, 0, 0.02), (-1, -1, 0.1),
             (0, -2, 0.05), (1, -1, 0.1), (1, 0, 0.07), (1, 1, 0.01),
             (2, 0, 0.02), (0, -1, 0)]

 

나머지 우, 상, 하 로 이동하는 토네이도도 규칙을 찾아 선언해줍니다.

move_right = [(x, -y, z) for x, y, z in move_left]
move_up = [(y, x, z) for x, y, z in move_left]
move_down = [(-y, x, z) for x, y, z in move_left]

 

토네이도를 처음부터 끝까지 이동시키고, 모래가 격자 밖으로 나간 양을 return하는 함수 tornado 입니다.

방향을 두번 바꿀때마다 토네이도의 이동 거리가 1씩 증가합니다.

def tornado():
    x, y = N//2, N//2
    d = 0
    out = 0
    change_d = 0
    length = 1
    while True:
        if change_d == 2:
            change_d = 0
            length += 1
        for i in range(length):
            x, y = dx[d] + x, dy[d] + y

            if [x, y] == [0, -1]:
                return out
            out += move(x, y, d)

        d = (d + 1) % 4
        change_d += 1
    return

print(tornado())

 

토네이도의 이동 방향에 맞게 알맞은 토네이도를 선택해주고, 모래를 이동시키는 함수 move입니다.

def move(x, y, d):
    if d == 0:
        move_list = move_left
    if d == 1:
        move_list = move_down
    if d == 2:
        move_list = move_right
    if d == 3:
        move_list = move_up

    out = 0
    total = board[x][y]
    for m in move_list:
        r, c, p = m
        nx, ny = x + r, y + c
        if 0 <= nx < N and 0 <= ny < N:
            if p != 0:
                board[nx][ny] += int(board[x][y] * p)
                total -= int(board[x][y] * p)
            else:
                board[nx][ny] += total
        else:
            if p != 0:
                out += int(board[x][y] * p)
                total -= int(board[x][y] * p)
            else:
                out += total

    board[x][y] = 0
    return out

 

백준 20057 마법사 상어와 토네이도 Python 코드였습니다.

감사합니다.

728x90
반응형