ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [알고리즘] 나무 재테크 - 구현
    알고리즘 2024. 3. 20. 17:27
    728x90

    문제

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

     

    16235번: 나무 재테크

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

    www.acmicpc.net

     

    풀이 팁

    1. 이 문제는 단순히 조건을 따라가면서 풀면 되는 문제인데, 가장 중요한 점은 시간복잡도 이다.

    -> 나는 처음에 단순히 3차원 배열 만들면서 배열을 초기화 시키면서 했다 ( 가장 아래에 처음 코드를 넣어 놓겠다 )

    -> 읽어보면 초기화를 엄청 시키면서 했는데, 나는 이 부분이 시간초과의 원인이라고 생각한다 ( 테코는 다 맞음 )

     

    2. 시간 초과를 줄이기 위해서 한일 ( 여기 팁은 질문 게시판에서 얻었다 )

    - 3차원 배열의 가장 안쪽은 list가 아닌 deque로 접근

    - sys.stdin.readline 사용 ( 근데 이건 크게 도움이 된지 모르겠음 )

    - 함수 줄이기 ( spring, summer, fall, winter 4개를 중복되는 코드는 묶어서 2개로 줄임 )

     

    코드

    import sys
    from collections import deque
    
    input = sys.stdin.readline
    
    n,m,k = map(int,input().split())
    
    dxs, dys = [-1,-1,-1,0,1,1,1,0],[-1,0,1,1,1,0,-1,-1]
    
    # 겨울마다 주는 양분
    extra_feed = [
        list(map(int,input().split()))
        for _ in range(n)
    ]
    
    # 트리
    tree = [
        [deque() for _ in range(n)]
        for _ in range(n)
    ]
    
    # 기본 양분
    feed = [
        [5 for _ in range(n)]
        for _ in range(n)
    ]
    
    for _ in range(m):
        x,y,age = map(int,input().split())
        tree[x-1][y-1].append(age)
    
    def in_range(x,y):
        return 0<=x<n and 0<=y<n
    
    def spring_summer():
        for i in range(n):
            for j in range(n):
                dead = 0
                new_tree = deque()
                for age in tree[i][j]:
    
                    if feed[i][j] >= age:
                        feed[i][j] -= age
                        new_tree.append(age+1)
                    else:
                        dead += age // 2
                
                feed[i][j] += dead
                tree[i][j] = new_tree
    
    def fall_winter():
        tmp_tree = []
        for x in range(n):
            for y in range(n):
                for age in tree[x][y]:
                    if age % 5 == 0:
                        for dx, dy in zip(dxs, dys):
                            nx,ny = x + dx, y + dy
    
                            if not in_range(nx,ny):
                                continue
    
                            tmp_tree.append((nx,ny))
                    else:
                        continue
                feed[x][y]  += extra_feed[x][y]
                
        for pos in tmp_tree:
            x,y = pos
            tree[x][y].appendleft(1)
    
    ans = 0
    def count_tree():
        global ans
    
        for i in range(n):
            for j in range(n):
                ans += len(tree[i][j])
    
    for _ in range(k):
        spring_summer()
        fall_winter()
    
    count_tree()
    print(ans)

     

     

     

    [ 처음 코드 ( 참조용 ) ]

    import sys
    from collections import deque
    import heapq
    
    input = sys.stdin.readline
    
    n,m,k = map(int,input().split())
    
    dxs, dys = [-1,-1,-1,0,1,1,1,0],[-1,0,1,1,1,0,-1,-1]
    
    # 겨울마다 주는 양분
    extra_feed = [
        list(map(int,input().split()))
        for _ in range(n)
    ]
    
    # 트리
    tree = [
        [[] for _ in range(n)]
        for _ in range(n)
    ]
    
    temp_tree = [
        [[] for _ in range(n)]
        for _ in range(n)
    ]
    
    dead_tree = []
    
    # 기본 양분
    feed = [
        [5 for _ in range(n)]
        for _ in range(n)
    ]
    
    for _ in range(m):
        x,y,age = map(int,input().split())
        tree[x-1][y-1].append(age)
    
    def in_range(x,y):
        return 0<=x<n and 0<=y<n
    
    def init_tree():
        for i in range(n):
            for j in range(n):
                temp_tree[i][j] = []
    
    def clear_dead_tree():
        global dead_tree 
    
        dead_tree = []
    
    def spring():
        global dead_tree
        init_tree()
    
        for i in range(n):
            for j in range(n):
                tree[i][j].sort()
                
                idx = 0
    
                while feed[i][j] > 0:
                    if idx >= len(tree[i][j]):
                        break
    
                    if feed[i][j] >= tree[i][j][idx]:
                        feed[i][j] -= tree[i][j][idx]
                        idx += 1
                    else:
                        feed[i][j] = 0
                        break
                
                for age in tree[i][j][idx:]:
                    dead_tree.append((i,j,age))
    
                tree[i][j] = tree[i][j][:idx] 
        
        
        for i in range(n):
            for j in range(n):
                for age in tree[i][j]:
                    temp_tree[i][j].append(age+1)
        
        for i in range(n):
            for j in range(n):
                tree[i][j]  = temp_tree[i][j]
    
    def summer():
        global dead_tree
        
        for i,j,age in dead_tree:
            feed[i][j] += age // 2
    
    def fall_winter():
        for x in range(n):
            for y in range(n):
                for age in tree[x][y]:
                    if age % 5 == 0:
                        for dx,dy in zip(dxs, dys):
                            nx,ny = x + dx, y + dy
    
                            if not in_range(nx,ny):
                                continue
    
                            tree[nx][ny].append(1)
                    else:
                        continue
                
                feed[x][y] += extra_feed[x][y]
    
    ans = 0
    def count_tree():
        global ans
    
        for i in range(n):
            for j in range(n):
                ans += len(tree[i][j])
    
    for _ in range(k):
        spring()
        summer()
        fall_winter()
    
    count_tree()
    print(ans)

    '알고리즘' 카테고리의 다른 글

    [알고리즘] 미세먼지 안녕 - bfs/구현  (2) 2024.03.22
    [ 알고리즘 ] 아기상어 - bfs  (0) 2024.03.21
    [알고리즘] - 조합  (0) 2024.03.15
    [알고리즘] 경사로 - 구현  (0) 2024.03.13
    [알고리즘] 연구소 - dfs/백트  (0) 2024.03.12
Designed by Tistory.