[파이썬] 백준 20057번 마법사 상어와 토네이도
작성:
백준 #20057 마법사 상어와 토네이도
# 인덱스 1부터 시작 (==(0,0) 까지 이동한후 소멸)
# 항상 가운데부터 토네이도 출발. (가운데의 모래 양은 0)
# N은 홀수
# 출력: 격자 밖으로 나간 모래 양
# 풀이 방향
# 1. 토네이도 이동 방향 (날아갈 위치 지정 & 방향)
# -> 좌표와 방향 return하는 함수 만들기
# 2. 모래 날아가는 것
# -> 방향도 함께 체크
# -> 격자 밖으로 나가는 모래 양 모아서 return하는 함수 만들기
# 회전 패턴
# 1 1 2 2 3 3 4 4 4 => N = 5
# 1 1 2 2 3 3 4 4 5 5 6 6 6 => N = 7
def idx(n):
y = x = n // 2
num = 1
dy = [0, 1, 0, -1]
dx = [-1, 0, 1, 0]
num_cnt = 0 # num_cnt가 num이 되면 방향 바꾸기
dir_cnt = 0 # dir_cnt가 2가 되면 num += 1
direc = 0
while num < n:
if num == n: break
y += dy[direc]
x += dx[direc]
yield y, x, direc
num_cnt += 1
if num_cnt == num:
direc = (direc + 1) % 4
dir_cnt += 1
num_cnt = 0
if dir_cnt == 2:
num += 1
dir_cnt = 0
else:
for _ in range(1, n):
y += dy[direc]
x += dx[direc]
yield y, x, direc
def sand(y, x, direc, amount):
global N, field
field[y][x] = 0
dy = [0, 1, 0, -1]
dx = [-1, 0, 1, 0]
idx = 1 if direc & 1 else 0
out = 0
# 1% = dy, dx - 1칸 // dy가 0이면 y로 +-1, dx가 0이면 x로 +-1
# 7% = dy가 0이면 dy +- 1, dx 상동
# 2% = dy가 0이면 dy +- 2
# 10% = dy, dx + 1칸 // dy가 0이면 y로 +-1, dx 상동
# 5% = dy, dx + 2칸
# a = dy, dx + 1칸
# direc & 1 => dx가 0
p = [0.01, 0.01, 0.07, 0.07, 0.02, 0.02, 0.1, 0.1, 0.05, 0]
res = [0 for _ in range(len(p))]
for i in range(len(p)):
temp_amount = int(p[i] * amount)
if i in (0, 1):
d = (direc + 3) % 4 if i == 0 else (direc + 1) % 4
ny = y - dy[direc] + dy[d]
nx = x - dx[direc] + dx[d]
elif i in (2, 3):
d = (direc + 3) % 4 if i == 2 else (direc + 1) % 4
ny = y + dy[d]
nx = x + dx[d]
elif i in (4, 5):
d = (direc + 3) % 4 if i == 4 else (direc + 1) % 4
ny = y + dy[d] * 2
nx = x + dx[d] * 2
elif i in (6, 7):
d = (direc + 3) % 4 if i == 6 else (direc + 1) % 4
ny = y + dy[direc] + dy[d]
nx = x + dx[direc] + dx[d]
elif i == 8:
ny = y + dy[direc] * 2
nx = x + dx[direc] * 2
else:
ny = y + dy[direc]
nx = x + dx[direc]
temp_amount = amount - sum(res)
res[i] = temp_amount
if 0 <= ny < N and 0 <= nx < N:
field[ny][nx] += temp_amount
else:
out += temp_amount
return out
N = int(input())
field = [list(map(int, input().split())) for i in range(N)]
result = 0
for y, x, direc in idx(N):
result += sand(y, x, direc, field[y][x])
print(result)
댓글남기기