문제링크: https://www.codetree.ai/frequent-problems/atom-collision/description
코드트리
국가대표가 만든 코딩 공부의 가이드북 코딩 왕초보부터 꿈의 직장 코테 합격까지, 국가대표가 엄선한 커리큘럼으로 준비해보세요.
www.codetree.ai
시뮬레이션 문제. 원자의 위치를 갱신하면서 엉뚱한 갑을 넣어줘서 한참 해맸다. 남아있는 원자들만 따로 관리하고 원자들을 이동시킨 위치를 딕셔너리의 키값으로 해서 충돌 여부를 확인하도록 했다.
걸린 시간: 1시간 8분 52초
# 문제 링크: https://www.codetree.ai/frequent-problems/atom-collision/description
from collections import defaultdict
n, m, k = tuple(map(int, input().split()))
# [[행, 열, 질량, 속력, 방향]...]
atomics = [
list(map(int, input().split()))
for _ in range(m)
]
# 0부터 인덱스 시작하도록
for i in range(m):
atomics[i][0] -= 1
atomics[i][1] -= 1
dys = [-1, -1, 0, 1, 1, 1, 0, -1]
dxs = [0, 1, 1, 1, 0, -1, -1, -1]
def next_pos(y, x, s, d):
ny = y + s * dys[d]
nx = x + s * dxs[d]
ny %= n
nx %= n
return (ny, nx)
def composite(pos, atoms):
sum_of_weight = 0
sum_of_speed = 0
is_udlr = False
is_cross = False
for m, s, d in atoms:
sum_of_speed += s
sum_of_weight += m
# 상하좌우
if d % 2 == 0:
is_udlr = True
# 대각선 방향
if d % 2 == 1:
is_cross = True
next_weight = sum_of_weight // 5
next_speed = sum_of_speed // (len(atoms))
if next_weight == 0:
return []
# 대각 상하좌우 모두 나온 경우
if is_udlr and is_cross:
return [(pos[0], pos[1], next_weight, next_speed, i * 2 + 1) for i in range(4)]
# 둘 중에 하나만 나온 경우
else:
return [(pos[0], pos[1], next_weight, next_speed, i * 2) for i in range(4)]
def simulate():
global atomics
board = defaultdict(list)
for y, x, m, s, d in atomics:
ny, nx = next_pos(y, x, s, d)
board[(ny, nx)].append((m, s, d))
next_atoms = []
for pos, atoms in board.items():
# 해당 위치에서 겹치는 경우
if len(atoms) > 1:
next_atoms += composite(pos, atoms)
# 해당 위치에서 겹치지 않는 경우
else:
next_atoms.append((pos[0], pos[1], atoms[0][0], atoms[0][1], atoms[0][2]))
atomics = next_atoms
for _ in range(k):
simulate()
print(sum([x[2] for x in atomics]))
'문제 해결 > 코드트리' 카테고리의 다른 글
[코드트리] 미로 타워 디펜스 - python (0) | 2022.10.13 |
---|---|
[코드트리] 색깔 폭탄 - python (0) | 2022.10.13 |
[코드트리] 불안한 무빙워크 - python (0) | 2022.10.12 |