문제 링크
풀이
문제 이해가 잘 안돼서 애먹은 ..
1. 중앙에서부터 시작하는 토네이도 이동 규칙은 다음과 같다.
왼쪽 1번 -> 아래 1번 -> 오른쪽 2번 -> 위 2번 > 왼쪽 3번 -> 아래 3번 ...
따라서 홀수번째 일 때 왼쪽, 아래 이동 시 모래 양을 계산해주었고
짝수번째 일 때 오른쪽, 위 이동 시 모래 양을 계산해주었다.
2. 방향에 따른 모래 비율을 저장해주었다.
left, right, down, up 배열에 방향 별 현재 위치에서 이동 위치까지의 상대적 인덱스 차이와 함께, 이동 위치의 비율을 저장해주었다.
(dx, dy, 비율)
3. 이동 시 모래 계산은 다음과 같다.
1) 1번에서 구한 이동 횟수만큼 방향에 맞게 이동시켜주며 현재 위치를 갱신한다.
- y 가 0 보다 작다면, 토네이도 이동이 끝난 것이므로 종료하면 된다.
2) 2번에서 기록해둔 현재 방향에 따른 모래 이동 위치 및 비율에 따라 이동할 모래양 new_sand를 구한다.
현재 위치의 모래양 * 비율
3-1) 모래 이동 위치가 범위를 벗어나지 않는다면, 모래를 이동시킨다.
3-2) 모래 이동 위치가 범위를 벗어난다면, ans 에 더한다. -> 구하고자 하는 값
4) 마지막 방향에는 a의 상대적 위치를 넣어, 위에서 이동시킨 모래양을 원래 있던 양에서 뺀 값을 구하고 3)번을 수행한다.
# https://www.acmicpc.net/problem/20057
def count(cnt, dx, dy, direct):
global ans, x, y
# 현재 위치 갱신
for _ in range(cnt):
x += dx
y += dy
# 이동 종료
if y < 0 :
break
# 이동한 전체 양
total = 0
for dx, dy, z in direct:
nx = x + dx
ny = y + dy
if z == 0 :
new_sand = graph[x][y] - total
else :
new_sand = int(graph[x][y] * z)
total += new_sand
if 0<= nx < n and 0 <= ny < n:
graph[nx][ny] += new_sand
else :
ans += new_sand
n = int(input())
graph = []
for _ in range(n):
graph.append(list(map(int,input().split())))
# 방향 별 이동 위치와 비율 저장
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]
# 위로 이동할 때
up = [(y,x,z) for x,y,z in left]
# 아래로 이동할 때
down = [ (-y,x,z) for x, y, z in left]
x = n //2
y = n //2
ans = 0
for i in range(1, n+1):
# 홀수 일 때 왼쪽, 아래 이동
if i % 2 != 0 :
# (이동 횟수, dx, dy, 방향 전달 )
count(i, 0, -1, left)
count(i, 1, 0, down)
# 짝수 일 때 오른쪽, 위 이동
else :
count(i, 0, 1, right)
count(i, -1, 0, up)
print(ans)
'개발 > algorithm' 카테고리의 다른 글
[백준 14499번] 주사위 굴리기 - python (0) | 2022.10.06 |
---|---|
[백준 20058번] 마법사 상어와 파이어스톰 - python (0) | 2022.10.05 |
[백준 21610번] 마법사 상어와 바비라기 - python (1) | 2022.10.05 |
[백준 21608번] 상어 초등학교 - Python (0) | 2022.10.04 |
[백준 19237번] 어른 상어 (1) | 2022.10.04 |