본문 바로가기
알고리즘/[python] 백준 BOJ

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

by Alan_Kim 2023. 6. 23.
728x90
반응형

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

 

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

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

www.acmicpc.net

 

문제 해결

  • 토네이도의 움직임을 관찰한 다음 움직이는 모래를 그래프로 이동시켜 그래프를 빠져나가는 모래의 양을 구하는 문제이다.
  • 토네이도의 움직임의 규칙성 부터 찾아야한다. 서, 남, 동, 북 방향으로 순서대로 움직이며 서,남/동,북 으로 바뀔 때 마다 움직이는 칸의 개수가 한 칸 씩 증가한다. 이를 먼저 구현해야한다.
  • 그다음 모래가 흩날리는 영역을 구해야하는데... 이는 서쪽방향으로 움직일 때 주어진 샘플을 보고 y좌표에서 얼만큼 떨어져 있는지 (dx,dy,날아가는 %)를 리스트 안에 저장해서 하나씩 계산을 시켜야한다.
  • 그리고 남은 남쪽, 동쪽, 북쪽으로 움직일 때는 left리스트의 좌표를 회전시킬줄 알아야한다.(이것이 어렵지만 많이 나오는 유형이다.)
  • 이 두가지를 유의하면 구현이 어렵지 않다.

 

CODE

def in_range(i,j):
    if 0<=i<n and 0<=j<n:
        return True
    return False
def move(i,j,dir):
    global answer
    if j<0:
        return
    total = 0    
    for dx, dy, z in dir:
        ni = i + dx
        nj = j + dy
        if z==0:
            new_sand = board[i][j] - total
        else:
            new_sand = int(board[i][j]*z)
            total += new_sand
        if in_range(ni,nj):
            board[ni][nj] += new_sand
        else:
            answer += new_sand
    board[i][j] = 0
if __name__=='__main__':
    n = int(input())
    board = [list(map(int,input().split())) for _ in range(n)]
    left = [(1,1,0.01), (-1,1,0.01),(1,0,0.07),(-1,0,0.07),(1,-1,0.1),
            (-1,-1,0.1), (2,0,0.02),(-2,0,0.02),(0,-2,0.05),(0,-1,0)]
    right = [(x,-y,z) for x, y, z in left]
    down = [(-y,x,z) for x, y, z in left]
    up = [(y,x,z) for x,y,z in left]
    trans = {0:left, 1:down, 2:right, 3:up}
    x=n//2;y=n//2
    dxs = [0,1,0,-1]
    dys = [-1,0,1,0]
    cnt = 0
    answer = 0
    num = 0
    stop=False
    while not stop:
        num %=4
        if num%2==0:
            cnt += 1
        for _ in range(cnt):
            x += dxs[num]
            y += dys[num]
            move(x,y,trans[num])
            if x==0 and y==0:
                stop = True
        num += 1
    print(answer)
728x90
반응형

댓글