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

Byeonghyeon Kim·2021년 7월 20일
0

알고리즘문제

목록 보기
92/93
post-thumbnail

링크

백준 20057 마법사 상어와 토네이도


삼성스타일의 시뮬레이션 문제
문제를 잘 읽고 그대로만 잘 구현하면 풀리는 문제이다.
개인적으로 이런스타일을 좋아하지는 않는다.. 꼭 하다보면 뭐하나 놓쳐서 디버깅 하는데 시간을 한참 잡아먹어서 ㅠㅠ

모래를 이동하는 좌표의 경우 왼쪽 하나만 만들어주고 나머지는 그걸 계산해서 만들어줬다.

토네이도의 이동같은 경우엔 좌하우상 순으로 계속 돌아가게 만들되 돌았을 때 이미 방문한 곳이면 해당 방향을 유지하도록 만들었다.


정답 코드

import sys; input = sys.stdin.readline

# 모래 이동
left = [[0, -2, 0.05], [1, -1, 0.1], [-1, -1, 0.1], [1, 0, 0.07], [-1, 0, 0.07], [2, 0, 0.02], [-2, 0, 0.02], [1, 1, 0.01], [-1, 1, 0.01], [0, -1, 1]]
right = [[r, -c, ratio] for r, c, ratio in left]
up = [[c, r, ratio] for r, c, ratio in left]
down = [[-c, r, ratio] for r, c, ratio in left]
def blow(tr, tc, dir):
    global ans
    tmp = 0
    if dir == 0:
        for r, c, ratio in left:
            if ratio == 1:
                move_sand = sand[tr][tc] - tmp
            else:
                move_sand = int(sand[tr][tc] * ratio)
                tmp += move_sand
            if 0 <= tr + r < N and 0 <= tc + c < N:
                sand[tr + r][tc + c] += move_sand
            else:
                ans += move_sand

    if dir == 1:
        for r, c, ratio in down:
            if ratio == 1:
                move_sand = sand[tr][tc] - tmp
            else:
                move_sand = int(sand[tr][tc] * ratio)
                tmp += move_sand
            if 0 <= tr + r < N and 0 <= tc + c < N:
                sand[tr + r][tc + c] += move_sand
            else:
                ans += move_sand

    if dir == 2:
        for r, c, ratio in right:
            if ratio == 1:
                move_sand = sand[tr][tc] - tmp
            else:
                move_sand = int(sand[tr][tc] * ratio)
                tmp += move_sand
            if 0 <= tr + r < N and 0 <= tc + c < N:
                sand[tr + r][tc + c] += move_sand
            else:
                ans += move_sand

    if dir == 3:
        for r, c, ratio in up:
            if ratio == 1:
                move_sand = sand[tr][tc] - tmp
            else:
                move_sand = int(sand[tr][tc] * ratio)
                tmp += move_sand
            if 0 <= tr + r < N and 0 <= tc + c < N:
                sand[tr + r][tc + c] += move_sand
            else:
                ans += move_sand

    sand[tr][tc] = 0

def move(tr, tc):
    # 좌 하 우 상
    dir = 0
    dr = [0, 1, 0, -1]
    dc = [-1, 0, 1, 0]
    while tr != 0 or tc != 0:
        nr = tr + dr[dir]
        nc = tc + dc[dir]
        if not visit[nr][nc]:
            visit[nr][nc] = 1
            tr, tc = nr, nc
            blow(tr, tc, dir)
            dir += 1
            if dir == 4:
                dir = 0
        else:
            dir -= 1
            if dir < 0:
                dir = 3

ans = 0
N = int(input())
sand = [list(map(int, input().split())) for _ in range(N)]
visit = [([0] * N) for _ in range(N)]
tr, tc = N // 2, N // 2
visit[tr][tc] = 1

move(tr, tc)

print(ans)

알게된 것👨‍💻

  • 시뮬레이션 풀땐 찬찬히 하나하나 정리해가면서 놓치지 않게 풀자
profile
자기 주도 개발전 (개발, 발전)

0개의 댓글