[코딩테스트 공부] 나무 자르기
출처 : https://www.acmicpc.net/problem/2805
문제 풀이에 앞서 문제를 분석해봅시다
일단 시간 제한은 1초이고, N은 100만까지 허용이 되어있는 상태입니다. 당연하게도 O(N^2)의 복잡도를 가지게 알고리즘을 구현하면 실패합니다. 따라서 이분탐색을 이용하여 문제를 해결해야합니다.
어떻게 풀어야할까요..?
우리가 구하고자 하는 바부터 확실하게 하고 갑시다. 우리가 구해야하는 것은, 상근이가 적어도 M의 길이만큼 목재를 가져갈 수 있도록 하는 톱날의 최대 높이를 구하는게 관건입니다. 따라서, 이분탐색의 기준을 톱날의 길이에 맞춰서 알고리즘을 설계하면 충분할 듯 합니다.
일단 코드부터 확인해봅시다!
import sys
input = sys.stdin.readline
N, M = map(int, input().split())
height_list = list(map(int, input().split()))
start = 1
end = max(height_list)
while start <= end:
mid = (start + end) // 2
sum = 0
for tree_height in height_list:
tmp = 0 if tree_height <= mid else tree_height - mid
sum += tmp
if sum >= M:
start = mid + 1
else:
end = mid - 1
print(end)
이진탐색의 취지에 맞게, mid에 따라서 start, mid의 값을 변경시키면서 범위를 좁히도록합니다!
그리고, 해당 mid의 값에 따라서 나무를 계속 잘라나가는데, 상식적으로 톱날의 높이가 나무의 높이보다 높거나 같은 경우에는 나무가 잘리지 않기 때문에 0을 더하고, 아닌 경우에는 나무의 높이에서 mid 만큼 빼서 sum에 반영해주면 됩니다. 반박시 초능력자
그리고 만일 sum이 원하는 길이보다 컸을 경우에는, 높이를 더 높여도 된다는 뜻이기 때문에 start를 조절하고, 아닌 경우에는 높이를 낮춰야한다는 뜻이므로 end를 조절합니다.
마지막으로, end를 출력해주면 문제는 해결됩니다.
Author And Source
이 문제에 관하여([코딩테스트 공부] 나무 자르기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@18k7102dy/coding-test-fourth-1저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)