본문 바로가기

알고리즘/백준

[Python] 백준 20057: 마법사 상어와 토네이도

www.acmicpc.net/problem/20057

 

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

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

www.acmicpc.net

풀이 방법

  • 토네이도와 모래의 이동경로만 잘 잡아주면 풀 수 있는 문제였다. 
  • 토네이도는 (n//2, n//2)지점부터 시작해서 방향은 좌, 하, 우, 상을 반복하면서 해당 방향으로 1칸, 1칸, 2칸, 2칸, 3칸, 3칸, 4칸, 4칸, ... 이렇게 2를 주기로 칸수를 늘려서 같은 방향을 이동한다. (아래 이미지 참고)
  • 위를 기준으로 0부터 n*n-1까지 이동할 방향을 arr에 저장한다. arr에 맞춰서 한 칸씩 이동하면서 모래에 대해 처리한다.
  • 모래의 이동은 위아래 / 좌우로 나누어서 구현했다. (아래 이미지와 코드 참고)

전체 코드

# (x,y)에서 시작해서 d방향으로 토네이도가 이동할 때 모래 이동
def sand(x, y, d):
    global answer
    cx, cy = x+move[d][0], y+move[d][1]
    if not (0<=cx<n and 0<=cy<n and board[cx][cy]): return
    start = board[cx][cy]
    ax, ay = cx+move[d][0], cy+move[d][1]
    if d ==1 or d == 3:
        where = [(x,y-1, 0.01), (x,y+1, 0.01), (cx,cy-1, 0.07), (cx,cy+1, 0.07),
                 (cx,cy-2, 0.02), (cx,cy+2, 0.02), (ax,ay-1, 0.1), (ax,ay+1, 0.1),
                 (ax+move[d][0], ay+move[d][1], 0.05)]
    else:
        where = [(x-1,y, 0.01), (x+1,y, 0.01), (cx-1,cy, 0.07), (cx+1,cy, 0.07),
                 (cx-2,cy, 0.02), (cx+2,cy, 0.02), (ax-1,ay, 0.1), (ax+1,ay, 0.1),
                 (ax+move[d][0], ay+move[d][1], 0.05)]
    alpha = board[cx][cy]
    for i, j, per in where:
        temp = int(start*per)
        alpha -= temp
        if 0<=i<n and 0<=j<n:
            board[i][j] += temp
        else:
            answer += temp
    if 0<=ax<n and 0<=ay<n:
        board[ax][ay] += alpha
    else:
        answer += alpha
    board[cx][cy] = 0

n = int(input())
board = []
for i in range(n):
    board.append(list(map(int, input().split())))

# 토네이도 이동 경로
cnt = 1
temp = 0
j = 0
arr = [0]*(n*n-1)
while j < n*n-1:
    for i in range(cnt):
        if j >= n*n-1: break
        arr[j] = temp
        j+=1
    temp = (temp+1)%4
    for i in range(cnt):
        if j >= n*n-1: break
        arr[j] = temp
        j+=1
    cnt += 1
    temp = (temp+1)%4
move = [(0,-1), (1,0),(0,1),(-1,0)]
x, y = n//2, n//2
answer = 0
for i in arr:
    sand(x, y, i)
    x = x+move[i][0]
    y = y+move[i][1]
print(answer)
반응형