이번 문제는 삼성 기출 문제로, 시뮬레이션을 구현하는 문제였다. 파이어볼의 좌표가 범위를 벗어나면 어떻게 되는지에 대한 명시가 되어있지 않아 이 부분에 대해서만 질문 검색을 통해 순환한다는 것을 알아냈다. 파이어볼의 저장 방법은 인접 행렬에 값을 갱신하는 형태로 하였다. 시뮬레이션 문제이므로 각 기능에 대한 함수를 구현하였다.
move함수는 fireballs리스트를 순회하며 파이어볼이 존재할 때마다 호출하게 되고, 한번의 fireballs리스트 순회가 끝나면 sum_divide함수를 통해 파이어볼을 합치고 나누게 된다.
처음에 실수한 점은 파이어볼의 이동이 동시에 발생하는 것이므로 임시 리스트를 사용해야 했는데 이 부분을 놓쳐 하나의 파이어볼이 여러번 움직이게 되었다는 점이었다. 다른 실수로는 dy, dx방향을 주어진것과 반대로 구현하여 30분동안 삽질을 했다 ㅎ..
이러한 부분들을 수정하여 문제를 해결할 수 있었다.
from copy import deepcopy
n, m, k=map(int, input().split())
fireballs=[[[] for _ in range(n)] for _ in range(n)]
for _ in range(m):
r, c, mm, s, d=map(int, input().split())
fireballs[r-1][c-1].append((mm, s, d))
dy, dx=[-1, -1, 0, 1, 1, 1, 0, -1], [0, 1, 1, 1, 0, -1, -1, -1]
def move(y, x, fireball):
mi, si, di=fireball
ny, nx=(y+si*dy[di])%n, (x+si*dx[di])%n
tmp_fireballs[ny][nx].append((mi, si, di))
def sum_divide(y, x):
s_m=0
s_s=0
ds=[]
for i in range(len(fireballs[y][x])):
s_m+=fireballs[y][x][i][0]
s_s+=fireballs[y][x][i][1]
ds.append(fireballs[y][x][i][2])
s_m//=5
s_s//=len(fireballs[y][x])
fireballs[y][x]=[]
if s_m==0:
return
odd, even=0, 0
for d in ds:
if d%2==0:
even+=1
else:
odd+=1
if odd==len(ds) or even==len(ds):
for i in range(4):
fireballs[y][x].append((s_m, s_s, 2*i))
else:
for i in range(4):
fireballs[y][x].append((s_m, s_s, 2*i+1))
for _ in range(k):
tmp_fireballs = [[[] for _ in range(n)] for _ in range(n)]
for i in range(n):
for j in range(n):
if fireballs[i][j]:
for l in range(len(fireballs[i][j])):
move(i, j, fireballs[i][j][l])
fireballs=deepcopy(tmp_fireballs)
for i in range(n):
for j in range(n):
if len(fireballs[i][j])>=2:
sum_divide(i, j)
answer=0
for i in range(n):
for j in range(n):
if fireballs[i][j]:
for l in range(len(fireballs[i][j])):
answer+=fireballs[i][j][l][0]
print(answer)