Coding Test/BaekJoon_Python
백준 20057 <마법사 상어와 토네이도> Python
JunOnJuly
2023. 11. 24. 15:42
728x90
https://www.acmicpc.net/problem/20057
20057번: 마법사 상어와 토네이도
마법사 상어가 토네이도를 배웠고, 오늘은 토네이도를 크기가 N×N인 격자로 나누어진 모래밭에서 연습하려고 한다. 위치 (r, c)는 격자의 r행 c열을 의미하고, A[r][c]는 (r, c)에 있는 모래의 양을
www.acmicpc.net
구현문제입니다. 문제를 이해하기만 하면 나름 간단하게 풀 수 있습니다.
1. 모래를 날릴 때 소수점은 버린다. -> 버린 소수점 아래의 모래는 그 자리에 남아있다.
2. 맵 밖으로 날아간 모래 역시 소수점은 버린다.
이 점만 고려하면 구현만 충실히 하면 풀 수 있습니다.
def solution(N, data_list):
# 초반 모래의 양
init_sum_sand = 0
for data in data_list:
init_sum_sand += sum(data)
# 이동 거리
move_length = 1
# 이동 방향
move_dir = -1
# 현재 위치
now_x = N//2
now_y = N//2
# 순회하며 탐색
while True:
for _ in range(2):
# 이동 방향 + 1
move_dir += 1
for __ in range(move_length):
# 토네이도 이동
now_x, now_y = move_tornado(move_dir, now_x, now_y)
# 모래 이동
data_list = move_sand(data_list, now_x, now_y, move_dir, N)
# 0, 0 에 도달하면 끝
if not now_x and not now_y:
# 맵에 남아있는 모래의 양
left_sum_sand = 0
for data in data_list:
left_sum_sand += sum(data)
# 처음 모래의 양 - 남은 모래의 양
return init_sum_sand - left_sum_sand
# 두 번 꺾이면 이동거리 + 1
move_length += 1
# 토네이도가 이동하는 함수
def move_tornado(move_dir, now_x, now_y):
# 이동 가이드
move_guide_x = [0, 1, 0, -1]
move_guide_y = [-1, 0, 1, 0]
# 토네이도 위치
return now_x + move_guide_x[move_dir%4], now_y + move_guide_y[move_dir%4]
# 모래가 이동하는 함수
def move_sand(data_list, now_x, now_y, move_dir, N):
# 현 위치에 남은 모래
left_sand = data_list[now_x][now_y]
# 모래 이동 가이드
sand_move_guide_x = [-2, -1, -1, -1, 0, 1, 1, 1, 2, 0]
sand_move_guide_y = [0, -1, 0, 1, -2, -1, 0, 1, 0, -1]
sand_move_value = [2, 10, 7, 1, 5, 10, 7, 1, 2, -1]
# 현 위치의 모래량
now_sand_value = data_list[now_x][now_y]
# 가이드를 순회하며 모래 이동
for sand_x, sand_y, sand_value in zip(sand_move_guide_x,\
sand_move_guide_y,\
sand_move_value):
# 이동 방향 분기
if move_dir%4 == 0:
# 모래가 날아갈 위치
sand_moved_x = now_x + sand_x
sand_moved_y = now_y + sand_y
elif move_dir%4 == 1:
# 모래가 날아갈 위치
sand_moved_x = now_x - sand_y
sand_moved_y = now_y + sand_x
elif move_dir%4 == 2:
# 모래가 날아갈 위치
sand_moved_x = now_x - sand_x
sand_moved_y = now_y - sand_y
else:
# 모래가 날아갈 위치
sand_moved_x = now_x + sand_y
sand_moved_y = now_y - sand_x
# 날아갈 위치가 유효하면
if (sand_moved_x >=0 and sand_moved_x < N) and \
(sand_moved_y >= 0 and sand_moved_y < N):
# 마지막 alpha 에는 남은 모래 모두 이동
if sand_value == -1:
data_list[sand_moved_x][sand_moved_y] += left_sand
else:
# 날아갈 모래
moving_sand = int(now_sand_value * (sand_value / 100))
# 모래 날리기
data_list[sand_moved_x][sand_moved_y] += moving_sand
# 모래 빼주기
left_sand -= moving_sand
# 날아갈 위치가 유효하지 않으면
else:
# 날아갈 모래
moving_sand = int(now_sand_value * (sand_value / 100))
# 모래 빼주기
left_sand -= moving_sand
# 현 위치의 모래를 0으로 바꾸기
data_list[now_x][now_y] = 0
return data_list
N = int(input())
data_list = [list(map(int, input().split())) for _ in range(N)]
print(solution(N, data_list))
728x90