코드트리 나무타이쿤
n x n 격자의 칸에 리브로수의 각자 다른 높이와 각 년도의 이동 규칙이 주어질 때, 해당 년수가 모두 지나고 난 뒤 남아있는 리브로수 높이들의 총 합을 구하는 프로그램
n x n 격자에 서로 다른 높이를 가진 리브로수가 주어진다.
특수 영양제는 1 x 1 땅에 있는 리브로수의 높이를 1 증가시키며, 만약 해당 땅에 씨앗만 있는 경우에는 높이 1의 리브로수를 만들어낸다.
초기 특수 영양제는 n x n 격자의 좌하단의 4개의 칸에 주어진다.
⇒ [n-2][0], [n-2][1], [n-1][0], [n-1][1]
특수 영양제 이동 방향의 경우 1번부터 8번까지 → ↗ ↑ ↖ ← ↙ ↓ ↘으로 주어지며 이동 칸 수만큼 특수 영양제가 이동하게 된다.
⇒ dx = [0, 0, -1, -1, -1, 0, 1, 1, 1], dy = [0, 1, 1, 0, -1, -1, -1, 0, 1]
격자 바깥으로 나가면 반대편으로 돌아온다.
리브로수는 성장 규칙
다음 년도로 넘어가면 위의 4단계를 다시 반복한다.
(입력 및 선언)
(총 M년까지 반복)
(영양제가 그리드 안에 위치하도록 만들기)
(땅에 영양제 주기)
(인접 대각선 찾기)
(인접 대각선 높이 증가시키기)
(나무 자르기)
(나무 높이 총합)
dx = [0, 0, -1, -1, -1, 0, 1, 1, 1]
dy = [0, 1, 1, 0, -1, -1, -1, 0, 1]
N, M = map(int, input().split())
tree = []
nutri = [[N-2, 0], [N-2, 1], [N-1, 0], [N-1, 1]]
# 리브로수 높이 입력받기
for _ in range(N):
tree.append(list(map(int, input().split())))
# 영양제가 grid를 넘지 않게
def move_nutri(pos):
if pos < 0:
return pos + N
if pos >= N:
return pos % N
return pos
# 각 연도의 이동 규칙
for _ in range(M):
d, p = map(int, input().split())
# 영양제 이동
for i in range(len(nutri)):
nutri[i][0] = move_nutri(nutri[i][0] + dx[d] * p)
nutri[i][1] = move_nutri(nutri[i][1] + dy[d] * p)
# 땅에 영양제 주기
for n in nutri:
tree[n[0]][n[1]] += 1
# 인접 대각선 높이 증가시키기
arr = []
for i in range(len(nutri)):
cnt = 0
for d in [2, 4, 6, 8]:
nx = nutri[i][0] + dx[d]
ny = nutri[i][1] + dy[d]
if 0 <= nx < N and 0 <= ny < N:
# 높이가 1 이상이면 증가
if tree[nx][ny] > 0:
cnt += 1
arr.append([i, cnt])
for element in arr:
i = element[0]
cnt = element[1]
tree[nutri[i][0]][nutri[i][1]] += cnt
# 나무 자르기
for i in range(N):
for j in range(N):
if tree[i][j] >= 2 and ([i, j] not in nutri):
tree[i][j] -= 2
nutri.append([i, j])
# 높이 총 합
ans = 0
for i in tree:
for j in i:
ans += j
print(ans)