본문 바로가기
알고리즘 풀이/백준

[백준 16235] 나무재태크 (python)

by char_lie 2023. 4. 15.
반응형

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

 

16235번: 나무 재테크

부동산 투자로 억대의 돈을 번 상도는 최근 N×N 크기의 땅을 구매했다. 상도는 손쉬운 땅 관리를 위해 땅을 1×1 크기의 칸으로 나누어 놓았다. 각각의 칸은 (r, c)로 나타내며, r은 가장 위에서부터

www.acmicpc.net

나무 재태크 문제

나무를 심고, 봄 여름 가을 겨울이 지나갔을 때, 정해진 규칙대로 진행될 경우 최종적으로 생기는 나무의 수를 찾는 문제

for문을 이용한 반복구조, 3중 배열을 활용해여 해결 할 수 있었다.

📌문제 접근 포인트

1. 문제에 조건이 꽤 많다. 하나하나 정리해서 천천히 생각해보자. 조건을 놓칠 경우 꼬이게 될 수 있다.
2. 양분에 해당하는 리스트를 하나 따로 만들어주고, 여기서 꺼내와서 쓴 후, 값을 비교해주는 형태로 구현해보자.
3. 봄과 여름은 따로 구현하면 중복해서 탐색하는 부분이 생겨서 더 오래 걸릴 수 있다. 둘이 세트로 엮고, 나이만큼 비료를 먹고, 비료보다 크면 나머지는 다 죽여서 양분으로 만들어 버리는 과정을 구현해주자.
4. 가을에는 탐색해주면서, 조건에 맞게 5의 배수이면 주변에 나무가 생성되도록 구현해주자.
5. 겨울에는 처음 입력받은 값만큼 비료를 증가시켜주자 (4번과 5번을 하나로 묶어도 된다. 묶으면 연산이 조금이나마 줄어들긴한다)
6. 최종적으로 나무의 갯수를 세어 출력해주자

⚙ 내가 푼 정답 코드 (pypy에서만 통과)

# 조건 1. N*N크기의 땅, 가장 처음 양분은 모든 칸에 5
# 조건 2. M개의 나무를 구매해 땅에 심음
# 조건 3. 봄 : 나무가 자신의 나이만큼 양분먹고 나이 +1, 한칸에 여러 나무가 있으면 나이가 어린 나무부터 양분을 먹고 못먹으면 사망
# 조건 4. 여름 : 봄에 죽은 나무의 나이//2 -> 양분
# 조건 5. 가을 : if 나무나이 % 5 == 0 : 인접한 8칸에 나이가 1인 나무 번식
# 조건 6. 겨울 : 땅에 양분 추가

import sys
from collections import deque
N,M,K = map(int, sys.stdin.readline().split())
farm = [list(map(int, sys.stdin.readline().split())) for _ in range(N)]
tree = [list(map(int, sys.stdin.readline().split())) for _ in range(M)]
small_tree = [[0,1],[1,1],[1,0],[1,-1],[0,-1],[-1,-1],[-1,0],[-1,1]]
fertilizer = [[5]*N for _ in range(N)] # 조건 1
land = [[deque() for _ in range(N)] for _ in range(N)]
result = 0
while tree: # 최초 나무 심기
    r, c, age = tree.pop()
    land[r-1][c-1].append(age)

for _ in range(K): # K 년동안
    for i in range(N):
        for j in range(N):
            for k in range(len(land[i][j])):
                if fertilizer[i][j] >= land[i][j][k]: # 비료가 남아있으면
                    fertilizer[i][j] -= land[i][j][k] # 나무가 나이만큼 비료를 먹고
                    land[i][j][k] += 1 # 나무 나이 증가
                else : # 조건 4
                    for _ in range(k,len(land[i][j])): # 안남았단건 다 죽여야하니
                        x = land[i][j].pop()
                        fertilizer[i][j] += x//2 # 죽은 나무의 양분
                    break
                
    for i in range(N):
        for j in range(N):
            for k in range(len(land[i][j])): # 조건 5
                if land[i][j][k] % 5 == 0 :
                    for dy, dx in small_tree:
                        ny, nx = i + dy, j + dx
                        if 0 <= ny < N and 0 <= nx < N: # 범위 안벗어나면
                            land[ny][nx].appendleft(1) # 1살짜리 나무 친구들 생성
                
    for i in range(N): # 조건 6 #겨울 지나면
        for j in range(N):
            fertilizer[i][j] += farm[i][j] # 비료 증가

for i in range(N):
    for j in range(N):
        result += len(land[i][j])
print(result)

 

반응형

댓글