[Samsung] 2021-2 오후 1번 나무 타이쿤

Question

Language: Python

Difficulty: Gold 5

해당 문제에서 구현해야될 부분은 크게 3가지이다.

  1. 영양제의 이동
  2. 나무의 성장
  3. 영양제 생성

각 세부 과정은 아래와 같다

  1. 영양제 이동

영양제가 있는 자리에 대해서는 주어진 방향, 크기에 대해 좌표 이동을 수행한 후 해당 자리에 영양제를 투입한다. 투입한 나무는 높이가 1 자라게 된다.

#영양제의 이동
def move_nutrition(dir,size):
    global nutrition_map,tree_map

    new_nutrition_map=[[0] * n for _ in range(n)]

    for row in range(n):
        for col in range(n):
            #해당 자리에 영양제가 없는 경우
            if nutrition_map[row][col] == 0:
                continue
            
            next_row=(row+dy[dir-1]*size)%n
            next_col=(col+dx[dir-1]*size)%n

            new_nutrition_map[next_row][next_col]=1
            #해당 자리에 트리 높이 1씩 증가
            tree_map[next_row][next_col]+=1
    
    #새로운 영양제 정보 갱신
    for row in range(n):
        for col in range(n):
            nutrition_map[row][col]=new_nutrition_map[row][col]
  1. 나무의 성장

영양제가 뿌려진 자리의 경우 인접한 대각선 좌표들에 있는 나무를 검사해서 나무의 높이가 1이상인 칸의 갯수만큼 해당 자리의 나무의 높이를 증가시킨다.

#리브로수 크기 증가
def grow_tree():
    global tree_map
    grow_map=[[0] * n for _ in range(n)]

    for row in range(n):
        for col in range(n):
            #영양제가 없으면 넘어간다.
            if nutrition_map[row][col]==0:
                continue
            
            adjacent_count=0

            #대각선만 확인한다.
            for dir in range(1,9,2):
                next_row=row+dy[dir]
                next_col=col+dx[dir]

                
                #격자를 벗어나는 경우
                if not check_range(next_row,next_col):
                    continue

                #대각선으로 인접한 좌표에 나무의 높이가 1이상인 경우
                if tree_map[next_row][next_col]>=1:
                    adjacent_count+=1


            grow_map[row][col]+=(adjacent_count)

    #나무의 높이를 증가시킨다.
    for row in range(n):
        for col in range(n):
            tree_map[row][col]+=grow_map[row][col]
  1. 영양제 증식

기존에 영양제가 없었던 자리에서 트리의 높이가 2이상인 경우 해당 자리에 영양제가 생성된다.

#영양제 증식
def reproduce_nutrition():
    global nutrition_map
    new_nutrition_map=[[0] * n for _ in range(n)]

    for row in range(n):
        for col in range(n):
            #영양제가 없었고 트리의 높이가 2이상인 경우에 해당 자리에 영양제를 추가한다.
            if nutrition_map[row][col] == 0 and tree_map[row][col]>=2:
                new_nutrition_map[row][col]=1
                tree_map[row][col]-=2
    
    #새로운 영양제 정보 갱신
    for row in range(n):
        for col in range(n):
            nutrition_map[row][col]=new_nutrition_map[row][col]

Solution

#영양제의 이동
def move_nutrition(dir,size):
    global nutrition_map,tree_map

    new_nutrition_map=[[0] * n for _ in range(n)]

    for row in range(n):
        for col in range(n):
            #해당 자리에 영양제가 없는 경우
            if nutrition_map[row][col] == 0:
                continue
            
            next_row=(row+dy[dir-1]*size)%n
            next_col=(col+dx[dir-1]*size)%n

            new_nutrition_map[next_row][next_col]=1
            #해당 자리에 트리 높이 1씩 증가
            tree_map[next_row][next_col]+=1
    
    #새로운 영양제 정보 갱신
    for row in range(n):
        for col in range(n):
            nutrition_map[row][col]=new_nutrition_map[row][col]
            
                
#리브로수 크기 증가
def grow_tree():
    global tree_map
    grow_map=[[0] * n for _ in range(n)]

    for row in range(n):
        for col in range(n):
            #영양제가 없으면 넘어간다.
            if nutrition_map[row][col]==0:
                continue
            
            adjacent_count=0

            #대각선만 확인한다.
            for dir in range(1,9,2):
                next_row=row+dy[dir]
                next_col=col+dx[dir]

                
                #격자를 벗어나는 경우
                if not check_range(next_row,next_col):
                    continue

                #대각선으로 인접한 좌표에 나무의 높이가 1이상인 경우
                if tree_map[next_row][next_col]>=1:
                    adjacent_count+=1


            grow_map[row][col]+=(adjacent_count)

    #나무의 높이를 증가시킨다.
    for row in range(n):
        for col in range(n):
            tree_map[row][col]+=grow_map[row][col]

#영양제 증식
def reproduce_nutrition():
    global nutrition_map
    new_nutrition_map=[[0] * n for _ in range(n)]

    for row in range(n):
        for col in range(n):
            #영양제가 없었고 트리의 높이가 2이상인 경우에 해당 자리에 영양제를 추가한다.
            if nutrition_map[row][col] == 0 and tree_map[row][col]>=2:
                new_nutrition_map[row][col]=1
                tree_map[row][col]-=2
    
    #새로운 영양제 정보 갱신
    for row in range(n):
        for col in range(n):
            nutrition_map[row][col]=new_nutrition_map[row][col]
            

#범위 확인
def check_range(row,col):
    if row < 0 or row>=n or col < 0 or col>=n:
        return False
    return True

def solution():
    for dir,size in nutrition_movements:
        #영양제의 이동
        move_nutrition(dir,size)
        #리브로수 크기 증가
        grow_tree()
        #영양제 증식
        reproduce_nutrition()

    #리브로수 높이의 총합
    total_tree_count=0    
    for row in range(n):
        for col in range(n):
            total_tree_count+=tree_map[row][col]
    
    print(total_tree_count)

if __name__ == "__main__":
    n,m=map(int,input().split())
    tree_map=[list(map(int,input().split())) for _ in range(n)]
    nutrition_movements=[list(map(int,input().split())) for _ in range(m)]

    dy=[0,-1,-1,-1,0,1,1,1]
    dx=[1,1,0,-1,-1,-1,0,1]

    nutrition_map=[[0] * n for _ in range(n)]
    nutrition_map[n-1][0]=1
    nutrition_map[n-1][1]=1
    nutrition_map[n-2][0]=1
    nutrition_map[n-2][1]=1

    solution()

댓글남기기