https://www.acmicpc.net/problem/2805
import sys
n, m = map(int, sys.stdin.readline().rstrip().split())
forest = list(map(int, sys.stdin.readline().rstrip().split()))
# 절단기 설정 높이 h를 기준으로 이분 탐색 실행
start = 0
end = max(forest)
answer = 0
while start <= end:
h = (start + end) // 2
cutting = 0
# 현재 h로 자를 수 있는 길이 구하기
for tree in forest:
if tree > h:
cutting += (tree - h)
if cutting >= m:
# 일단 answer에 저장
answer = h
# h 늘려보기 (잘리는 길이 적게)
start = h + 1
elif cutting < m:
# h 줄여보기 (잘리는 길이 많게)
end = h - 1
print(answer)
📌나름의 포인트는 자른 길이가 m 이상일 때, 일단 answer에 저장하고 또 탐색을 하는 것이다. 적어도 m미터의 나무를 가져가기 위해 설정할 수 있는 높이의 최댓값을 찾는 것이므로, 더 큰 h에서도 m미터의 나무를 가져갈 수 있는 경우를 계속 찾아봐야 한다.
🔽참고로 처음 생각했던 풀이 방법은 이렇다.
import sys
# 이진 탐색
# target 이상인 요소가 처음 등장하는 인덱스를 찾는다
def my_binary_search(array, start, end, target):
while start <= end:
mid = (start+end)//2
if array[mid] >= target:
# mid 보다 앞의 인덱스가 존재할 때
if mid-1 >= 0:
# 만약 앞의 요소도 target보다 크면, 앞의 요소의 인덱스 리턴
if array[mid-1] > target:
return mid -1
# 아니면 그냥 mid 리턴
else:
return mid
elif array[mid] < target:
start = mid + 1
# target 이상인 요소가 존재하지 않는다
return -1
n, m = map(int, sys.stdin.readline().rstrip().split())
forest = list(map(int, sys.stdin.readline().rstrip().split()))
forest.sort() # 이진 탐색 수행하기 위해 정렬
# 절단기 설정 높이 h 이상인 나무가 처음 등장하는 인덱스를 찾는다
# h 도 이진탐색으로 해볼까?
found = False
h = forest[(n-1)//2] # h도 중간값에서 시작
while 0 <= h < forest[-1]:
idx = my_binary_search(forest, 0, n-1, h)
# 잘려나가는 나무들
cutting_trees = forest[idx:]
# 가져갈 수 있는 길이
summation = sum(cutting_trees) - len(cutting_trees)*h
if summation > m:
print(h)
# h의 길이 늘려본다
h += 1
elif summation < m:
print(h)
# h의 길이 줄여본다
h -= 1
else:
print(h)
break