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 설정하는 부분 다시 보기