[Python][백준] 16235번 나무 재테크

신남·2022년 9월 15일

https://www.acmicpc.net/problem/16235

공부 날짜 : 2022.09.15
정답 참조 여부 : X

나무를 심었을때 해가 변하면서 나무가 죽거나 번식을 반복하는데 k년 후의 나무의 개수를 구하는 문제이다.


리스트를 다루는게 많이 어려웠다.
처음에는 나무들의 좌표와 나이를 바탕으로 모든 나무를 반복하며 규칙에 따라가는 형태로 코드를 작성했으나
죽는 나무나 번식하는 나무가 리스트에 추가되고 제거되면 반복시 index가 변하기 때문에 어려움이 있고 이를 해결하기위해 새로 리스트를 만들고 하다보니 시간이 초과 되었다.

그래서 그냥 땅에 양분과 나무의 나이를 모두 저장해서 그 안에서만 추가 삭제를 반복하였다.


처음에 땅 선언을

ground = [[[5,[]]]*n for _ in range(n)]

로 선언 했더니 리스트 참조 문제로 같은 행이 모두 같은 값이 되었다.

코드를 싹 바꿔야 하나 고민이 많았지만 같은 열은 달라지는것을 참조하여

ground = [[[5,[]]for _ in range(n)] for _ in range(n)]

로 선언했더니 해결되었다.

리스트를 복사할때 copy문제와 리스트 값의 참조 할당 등이 아직 어려운듯 하다.

소스코드

import sys
input = sys.stdin.readline

#땅 크기, 나무의 개수, 기간
n,m,k = map(int,input().split())

#겨울에 추가될 양분의 양을 기록
S2D2_order = []
for _ in range(n):
    S2D2_order.append(list(map(int, input().split())))

#초기 땅의 양분은 5
#각 좌표에 [양분,[나무들의 나이]] 형태로 저장되어있음
ground = [[[5,[]]for _ in range(n)] for _ in range(n)]


#나무의 정보를 저장
for _ in range(m):
    x,y,year = map(int,input().split())
    #r,c가 1부터 시작하고 리스트는 0부터 시작하므로 -1씩 해준뒤 저장
    ground[x-1][y-1][1].append(year)


#봄 : 각 땅에 있는 나무를 탐색하여 양분 배분 and 사망 판정
#여름 : 죽은나무리스트를 받아 땅에 양분 배분
def spring_summer():
    #모든 좌표에 대해서
    for i in range(n):
        for j in range(n):
            #해당 번호 이후의 나무는 모두 사망
            death_tree = int(10e9)
            #나무를 나이순으로 정렬
            ground[i][j][1].sort()
            #각 나무들에 대해서 양분 배분
            for k in range(len(ground[i][j][1])):
                if ground[i][j][0] >= ground[i][j][1][k]:
                    ground[i][j][0] -= ground[i][j][1][k]
                    ground[i][j][1][k] += 1
                #양분이 부족하면 해당 나무번호 저장후 반복 멈춤
                else:
                    death_tree = k
                    break
            
            #나무의 나이만큼 양분 배분 후
            for l in range(death_tree, len(ground[i][j][1])):
                ground[i][j][0] += ground[i][j][1][l] // 2

            #나무 제거
            del ground[i][j][1][death_tree:]

        
        
#상하좌우대각선
dx = [0,1,0,-1,1,1,-1,-1]
dy = [1,0,-1,0,1,-1,1,-1]

#가을 : 나무리스트를 받아 나이가 5의 배수일때 번식
def autumn():
    #모든 좌표에 대해서
    for i in range(n):
        for j in range(n):
            #해당 좌표의 나무가
            for k in range(len(ground[i][j][1])):
                #5의 배수이면
                if ground[i][j][1][k]%5 == 0:
                    #모든 방향에 대해서
                    for dir in range(8):
                        nx = i + dx[dir]
                        ny = j + dy[dir]
                        #범위 이내일때
                        if 0 <= nx < n and 0 <= ny < n:
                            #새 나무 추가
                            ground[nx][ny][1].append(1)
          



#겨울 : S2D2에 입력받은대로 땅에 양분추가    
def winter():
    for i in range(n):
        for j in range(n):
            ground[i][j][0] += S2D2_order[i][j]

    

for _ in range(k):
    spring_summer()
    autumn()
    winter()

result = 0
for i in range(n):
    for j in range(n):
        result += len(ground[i][j][1])

print(result)

pypy3에서 제출해서 정답이 나왔습니다. python3환경에서 정답일지는 모릅니다.

0개의 댓글