import copy
n = int(input())
a = [list(map(int, input().split())) for _ in range(n)]
dx = [0, 1, 0, -1]
dy = [-1, 0, 1, 0]
dir = [0] * (n * n - 1)
# sand[방향][1 ~ 9] =
sand = [[[-1, 0, 0.01], [1, 0, 0.01], [-1, -1, 0.07], [1,-1, 0.07], [-2, -1, 0.02], [2, -1, 0.02], [-1, -2, 0.1], [1, -2, 0.1], [0, -3, 0.05]],
[[0, -1, 0.01], [0, 1, 0.01], [1, -1, 0.07], [1, 1, 0.07], [1, -2, 0.02], [1, 2, 0.02], [2, -1, 0.1], [2, 1, 0.1], [3, 0, 0.05]],
[[1, 0, 0.01], [-1, 0, 0.01], [-1, 1, 0.07], [1, 1, 0.07], [-2, 1, 0.02], [2, 1, 0.02], [-1, 2, 0.1], [1, 2, 0.1], [0, 3, 0.05]],
[[0, -1, 0.01], [0, 1, 0.01], [-1, -1, 0.07], [-1, 1, 0.07], [-1, 2, 0.02], [-1, -2, 0.02], [-2, 1, 0.1], [-2, -1, 0.1], [-3, 0, 0.05]]]
i = 0
iter = 1
maxiter = 1
k = 0
# 방향 전환 배열 만들기
while True:
if i == n * n - 1:
break
if iter < maxiter:
dir[i] = k % 4
iter += 1
elif iter == maxiter:
dir[i] = k % 4
iter += 1
if dir[i] == 1 or dir[i] == 3:
maxiter += 1
k += 1
iter = 1
i += 1
def move_sand(fx, fy, tx, ty, ax, ay, d, a):
ysand = a[tx][ty]
out = 0
for u in range(len(sand[d])):
# 모래가 이동할 좌표
sx, sy = fx + sand[d][u][0], fy + sand[d][u][1]
# 격자밖으로 날라가는 모래들
if sx < 0 or sy < 0 or sx >= n or sy >= n:
out += int(ysand * sand[d][u][2])
# y의 모래가 비율만큼 sx, sy로 이동
else:
a[sx][sy] += int(ysand * sand[d][u][2])
# 어떻게 되든 y에 있는 모래 양은 줄어든다.
a[tx][ty] -= int(ysand * sand[d][u][2])
# 알파로 이동하는 양은 y에 남은 양과 같다
# 알파가 밖으로 날아가면 날아가는 것에 추가
if ax < 0 or ay < 0 or ax >= n or ay >= n:
out += a[tx][ty]
# 알파가 격자를 벗어나지 않는다면
else:
a[ax][ay] += a[tx][ty]
a[tx][ty] = 0
return a, out
fx, fy = n // 2, n // 2
ans = 0
d = 0
while True:
if fx == 0 and fy == 0:
break
# y의 좌표
tx, ty = fx + dx[dir[d]], fy + dy[dir[d]]
# 알파의 좌표
ax, ay = tx + dx[dir[d]], ty + dy[dir[d]]
a, out = move_sand(fx, fy, tx, ty, ax, ay, dir[d], a)
ans += out
d += 1
fx, fy = tx, ty
print(ans)
하라는 대로 구현인데 정말 저 배열을 만들어야하나 고민이 좀 됐음
-> 다른 방법으로도 풀어보기(대칭이용)
n = int(input())
a = [list(map(int, input().split())) for _ in range(n)]
dx = [0, 1, 0, -1]
dy = [-1, 0, 1, 0]
dir = [0] * (n * n - 1)
# sand[방향][1 ~ 9] =
sand = [[[-1, 0, 0.01], [1, 0, 0.01], [-1, -1, 0.07], [1,-1, 0.07], [-2, -1, 0.02], [2, -1, 0.02], [-1, -2, 0.1], [1, -2, 0.1], [0, -3, 0.05]],
[[0, -1, 0.01], [0, 1, 0.01], [1, -1, 0.07], [1, 1, 0.07], [1, -2, 0.02], [1, 2, 0.02], [2, -1, 0.1], [2, 1, 0.1], [3, 0, 0.05]],
[[1, 0, 0.01], [-1, 0, 0.01], [-1, 1, 0.07], [1, 1, 0.07], [-2, 1, 0.02], [2, 1, 0.02], [-1, 2, 0.1], [1, 2, 0.1], [0, 3, 0.05]],
[[0, -1, 0.01], [0, 1, 0.01], [-1, -1, 0.07], [-1, 1, 0.07], [-1, 2, 0.02], [-1, -2, 0.02], [-2, 1, 0.1], [-2, -1, 0.1], [-3, 0, 0.05]]]
i = 0
iter = 1
maxiter = 1
k = 0
# 방향 전환 배열 만들기
while True:
if i == n * n - 1:
break
if iter < maxiter:
dir[i] = k % 4
iter += 1
elif iter == maxiter:
dir[i] = k % 4
iter += 1
if dir[i] == 1 or dir[i] == 3:
maxiter += 1
k += 1
iter = 1
i += 1
def move_sand(fx, fy, tx, ty, ax, ay, d):
out = 0
for u in range(len(sand[d])):
# 모래가 이동할 좌표
sx, sy = fx + sand[d][u][0], fy + sand[d][u][1]
# 격자밖으로 날라가는 모래들
if sx < 0 or sy < 0 or sx >= n or sy >= n:
out += int(a[tx][ty] * sand[d][u][2])
# y의 모래가 비율만큼 sx, sy로 이동
else:
a[sx][sy] += int(a[tx][ty] * sand[d][u][2])
# 어떻게 되든 y에 있는 모래 양은 줄어든다.
a[tx][ty] -= int(a[tx][ty] * sand[d][u][2])
# 알파로 이동하는 양은 y에 남은 양과 같다
# 알파가 밖으로 날아가면 날아가는 것에 추가
if ax < 0 or ay < 0 or ax >= n or ay >= n:
out += a[tx][ty]
a[tx][ty] = 0
return a, out
# 알파가 격자를 벗어나지 않는다면
a[ax][ay] += a[tx][ty]
a[tx][ty] = 0
return a, out
fx, fy = n // 2, n // 2
ans = 0
d = 0
while True:
if d == len(dir):
break
# y의 좌표
tx, ty = fx + dx[dir[d]], fy + dy[dir[d]]
# 알파의 좌표
ax, ay = tx + dx[dir[d]], ty + dy[dir[d]]
a, out = move_sand(fx, fy, tx, ty, ax, ay, dir[d])
ans += out
d += 1
fx, fy = tx, ty
print(ans)
자꾸 배열 a가 변하는데 값을 갖다쓰니까 잘못된 값이 나왔음
-> deepcopy 썻는데 시간 초과 -> 어차피 하나의 값만 저장하니까 걍 변수로 저장
import copy
n = int(input())
a = [list(map(int, input().split())) for _ in range(n)]
dx = [0, 1, 0, -1]
dy = [-1, 0, 1, 0]
dir = [0] * (n * n - 1)
# sand[방향][1 ~ 9] =
sand = [[[-1, 0, 0.01], [1, 0, 0.01], [-1, -1, 0.07], [1,-1, 0.07], [-2, -1, 0.02], [2, -1, 0.02], [-1, -2, 0.1], [1, -2, 0.1], [0, -3, 0.05]],
[[0, -1, 0.01], [0, 1, 0.01], [1, -1, 0.07], [1, 1, 0.07], [1, -2, 0.02], [1, 2, 0.02], [2, -1, 0.1], [2, 1, 0.1], [3, 0, 0.05]],
[[1, 0, 0.01], [-1, 0, 0.01], [-1, 1, 0.07], [1, 1, 0.07], [-2, 1, 0.02], [2, 1, 0.02], [-1, 2, 0.1], [1, 2, 0.1], [0, 3, 0.05]],
[[0, -1, 0.01], [0, 1, 0.01], [-1, -1, 0.07], [-1, 1, 0.07], [-1, 2, 0.02], [-1, -2, 0.02], [-2, 1, 0.1], [-2, -1, 0.1], [-3, 0, 0.05]]]
i = 0
iter = 1
maxiter = 1
k = 0
# 방향 전환 배열 만들기
while True:
if i == n * n - 1:
break
if iter < maxiter:
dir[i] = k % 4
iter += 1
elif iter == maxiter:
dir[i] = k % 4
iter += 1
if dir[i] == 1 or dir[i] == 3:
maxiter += 1
k += 1
iter = 1
i += 1
def move_sand(fx, fy, tx, ty, ax, ay, d, a):
tmp_a = copy.deepcopy(a)
out = 0
for u in range(len(sand[d])):
# 모래가 이동할 좌표
sx, sy = fx + sand[d][u][0], fy + sand[d][u][1]
# 격자밖으로 날라가는 모래들
if sx < 0 or sy < 0 or sx >= n or sy >= n:
out += int(a[tx][ty] * sand[d][u][2])
# y의 모래가 비율만큼 sx, sy로 이동
else:
tmp_a[sx][sy] += int(a[tx][ty] * sand[d][u][2])
# 어떻게 되든 y에 있는 모래 양은 줄어든다.
tmp_a[tx][ty] -= int(a[tx][ty] * sand[d][u][2])
# 알파로 이동하는 양은 y에 남은 양과 같다
# 알파가 밖으로 날아가면 날아가는 것에 추가
if ax < 0 or ay < 0 or ax >= n or ay >= n:
out += tmp_a[tx][ty]
# 알파가 격자를 벗어나지 않는다면
else:
tmp_a[ax][ay] += tmp_a[tx][ty]
tmp_a[tx][ty] = 0
return tmp_a, out
fx, fy = n // 2, n // 2
ans = 0
d = 0
while True:
if fx == 0 and fy == 0:
break
# y의 좌표
tx, ty = fx + dx[dir[d]], fy + dy[dir[d]]
# 알파의 좌표
ax, ay = tx + dx[dir[d]], ty + dy[dir[d]]
a, out = move_sand(fx, fy, tx, ty, ax, ay, dir[d], a)
ans += out
d += 1
fx, fy = tx, ty
print(ans)
deepcopy 로 시간 초과 난 코드 : 배열이 엄청나게 바뀌지 않는한 최대한 변수로 이용