목차
N개의 떡이 있을때 길이가 H인 절단기로 잘랐을 때 남은 떡 길이의 합이 적어도 M이 되게 하는 최대의 H를 찾아라.
입력 예시)
4 6
19 15 10 17
나의 코드
n,m=map(int,input().split())
arr=list(map(int,input().split()))
MM=0
left=0
right=max(arr)
while left<=right:
mid=(left+right)//2
temp=0
for x in arr:
if x-mid>0:
temp+=(x-mid)
if temp>=m :
left=mid+1
MM=mid
elif temp<m:
right=mid-1
print(MM)
간단한 어떤 값을 찾는게 아닌 특정한 조건을 부합하는 값들중 최대 값을 찾는 문제였다.
그 조건은 남는 떡이 최소 M이상이면서 최대로 크게 자를수 있는 H(절단기높이)였다.
우선 H(절단기높이)를 이진탐색을 하며 탐색한다.
탐색 이후 남은 떡의 양이 M보다 작은 경우 right=mid-1로 M보다 크거나 같은 경우는 left-mid-1로 범위를 좁혀가며 m이 최소값을 가지며 h가 최대 값을 가지는 범위를 찾았다.
정답 코드
# 떡의 개수(N)와 요청한 떡의 길이(M)을 입력
n, m = list(map(int, input().split(' ')))
# 각 떡의 개별 높이 정보를 입력
array = list(map(int, input().split()))
# 이진 탐색을 위한 시작점과 끝점 설정
start = 0
end = max(array)
# 이진 탐색 수행 (반복적)
result = 0
while(start <= end):
total = 0
mid = (start + end) // 2
for x in array:
# 잘랐을 때의 떡볶이 양 계산
if x > mid:
total += x - mid
# 떡볶이 양이 부족한 경우 더 많이 자르기 (오른쪽 부분 탐색)
if total < m:
end = mid - 1
# 떡볶이 양이 충분한 경우 덜 자르기 (왼쪽 부분 탐색)
else:
result = mid # 최대한 덜 잘랐을 때가 정답이므로, 여기에서 result에 기록
start = mid + 1
# 정답 출력
print(result)
전형적인 파라메트릭서치(원하는 조건을 만족하는 가장 알맞은 값을 찾는) 유형의 문제였다.
이 문제의 주요 아이디어는 '현재 이 높이로 자르면 조건(남은 떡의 길이가 M이상인가)을 만족하는가?'를 확인한 뒤 조건의 만족 여부(yes or no)에 따라 탐색 범위를 좁혀서 해결할 수 있다.
나의 코드와 완전히 동일하다 !
'코딩테스트[파이썬] > 이것이 코딩테스트다(이코테)' 카테고리의 다른 글
[다이나믹 프로그래밍] -1로 만들기 (0) | 2024.01.26 |
---|---|
[다이나믹 프로그래밍] 중복되는 연산을 줄이자 (4) | 2024.01.26 |
[이진탐색] 부품찾기 (1) | 2024.01.26 |
[이진탐색] 범위를 반씩 좁혀가는 탐색 (0) | 2024.01.26 |
[정렬] -두 배열의 원소 교체 (2) | 2024.01.26 |