[백준 삼성기출 X] 마법사 상어와 토네이도(python)

이진규·2022년 10월 7일
1

백준(PYTHON)

목록 보기
97/115

문제

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

나의 코드

"""

"""

N = int(input())
pan = [ list(map(int, input().split())) for _ in range(N) ]

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

windx = [
    [-1, 1, -2, 2, 0, -1, 1, -1, 1], # left
    [-1, -1, 0, 0, 2, 0, 0, 1, 1], # down
    [1, -1, 2, -2, 0, 1, -1, 1, -1], # right
    [1, 1, 0, 0, -2, 0, 0, -1, -1] # up
]
windy = [
    [1, 1, 0, 0, -2, 0, 0, -1, -1], # left
    [-1, 1, -2, 2, 0, -1, 1, -1, 1], # down
    [-1, -1, 0, 0, 2, 0, 0, 1, 1], # right
    [1, -1, 2, -2, 0, 1, -1, 1, -1] # up
]
rate = [1, 1, 2, 2, 5, 7, 7, 10, 10] # 흩날리는 모래의 비율

def wind(wx, wy, wd):
    sand = pan[wx][wy] # 현 위치에서의 모래의 양
    spread_sand = 0 # 범위 안으로 흩날린 모래의 양
    fail_sand = 0 # 범위 밖으로 흩날린 모래의 양

    # 흩날리는 9방향의 모래 처리
    for i in range(9):
        wmx = wx + windx[wd][i]
        wmy = wy + windy[wd][i]
        wind_sand = (sand * rate[i]) // 100
        spread_sand += wind_sand

        if not (0 <= wmx < N and 0 <= wmy < N): # 범위 밖으로 모래가 날라가면 모래 양 세기
            fail_sand += wind_sand
            continue

        pan[wmx][wmy] += wind_sand # 범위 안으로 모래가 날리면 더해주기 (원래 모래가 있으면 거기에 더해줘야함 -> +=)

    # 문제에서 a부분 처리(남은 모래의 양) - a의 모래 양은 (현위치 모래양 - 흩날린 전체 모래의 양) 임
    wmx = wx + dx[wd]
    wmy = wy + dy[wd]
    if not (0 <= wmx < N and 0 <= wmy < N):
        fail_sand += (sand - spread_sand)
    else:
        pan[wmx][wmy] += (sand - spread_sand)

    pan[wx][wy] = 0 # 현위치 모래는 0으로 한다.

    return fail_sand # 범위 밖으로 나간 모래의 양 반환

def move_sand(x, y):
    out_sand = 0 # 밖으로 나간 모래의 양
    visited = [[False] * N for _ in range(N)]
    d = -1 # 초기 방향 설정

    while True:

        if x == 0 and y == 0: # 시작점으로 돌아오면 반복문 탈출
            break

        visited[x][y] = True
        md = (d + 1) % 4
        mx = x + dx[md]
        my = y + dy[md]

        if visited[mx][my] == True: # 만약 꺾은 방향이 방문한 곳이라면 이전 방향으로 다시 가기위해 방향 되돌리기
            md = d
            mx = x + dx[md]
            my = y + dy[md]

        out_sand += wind(mx, my, md)
        x, y, d = mx, my, md # 방향 업데이트

    return out_sand

x, y = N // 2, N // 2
answer = move_sand(x, y)
print(answer)


    

설명

구현 문제 - windx, windy 설정하는 부분 다시 보기

참고 자료

https://unie2.tistory.com/992

profile
항상 궁금해하고 공부하고 기록하자.

0개의 댓글