백준, 마인크래프트, 18111

2024. 8. 26. 18:29ETC/Algorithm

[유형]

구현

 

[문제링크]

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

 

[요약]

목재를 충분히 모은 lvalue는 집을 짓기로 하였다. 하지만 고르지 않은 땅에는 집을 지을 수 없기 때문에 땅의 높이를 모두 동일하게 만드는 ‘땅 고르기’ 작업을 해야 한다.

lvalue는 세로 N, 가로 M 크기의 집터를 골랐다. 집터 맨 왼쪽 위의 좌표는 (0, 0)이다. 우리의 목적은 이 집터 내의 땅의 높이를 일정하게 바꾸는 것이다. 우리는 다음과 같은 두 종류의 작업을 할 수 있다.

  1. 좌표 (i, j)의 가장 위에 있는 블록을 제거하여 인벤토리에 넣는다.
  2. 인벤토리에서 블록 하나를 꺼내어 좌표 (i, j)의 가장 위에 있는 블록 위에 놓는다.

1번 작업은 2초가 걸리며, 2번 작업은 1초가 걸린다. 밤에는 무서운 몬스터들이 나오기 때문에 최대한 빨리 땅 고르기 작업을 마쳐야 한다. ‘땅 고르기’ 작업에 걸리는 최소 시간과 그 경우 땅의 높이를 출력하시오.

 

[문제풀이]

validate_number_of_blocks: 사용가능한 블록의 개수 확인한다.

calculate_time: target_height >= height의 경우 2번째 작업을, 반대의 경우 1번째 작업을 실행한다.

시간초과가 계속 발생했는데, 예서가 예전에 풀었던 코드를 공유해줬다. validate_number_of_blocks를 실행해서 불필요한 코드 실행 횟수를 감소시켜야한다.

import sys
def input():
    return sys.stdin.readline().rstrip()

# input
n, m, b = map(int, input().split())
board = [list(map(int, input().split())) for _ in range(n)]

# init
# 최저층, 최고층
MIN, MAX = 0, 256
# 한층의 최대 갯수, 좌표 위에 있는 블록의 총 개수
CNT, SUM = n*m, 0

blocks = [0] * (MAX+1)

# 해당 층이 최고층인 블록의 개수
for i in range(n):
    for j in range(m):
        blocks[board[i][j]] +=1
        SUM += board[i][j]

result_time = float('inf')
result_height = MAX

def validate_number_of_blocks(target_height):
    return SUM + b >= target_height * CNT

def calculate_time(target_height):
    time = 0
    for height,count in enumerate(blocks):
        if target_height >= height:
            time += (target_height - height) * count
        else:
            time += (height - target_height) * 2 *count
    return time

for h in range(MAX,MIN,-1):
    if not validate_number_of_blocks(h):
        continue
    t = calculate_time(h)
    if t < result_time:
        result_time = t
        result_height = h

print(result_time,result_height)

 

[참고] https://www.acmicpc.net/source/83003373 by 예서

'ETC > Algorithm' 카테고리의 다른 글

백준,N과 M (2),15650  (0) 2024.08.27
백준,N과 M (1),15649  (0) 2024.08.27
백준,퇴사,14501  (0) 2024.08.23
백준, 영화감독 숌,1436  (0) 2024.08.23
백준, 중앙값 구하기, 2696  (0) 2024.08.22