상세 컨텐츠

본문 제목

떡볶이 떡 만들기

코딩테스트/이진 탐색

by 수타. 2023. 6. 2. 10:36

본문

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

 

2805번: 나무 자르기

첫째 줄에 나무의 수 N과 상근이가 집으로 가져가려고 하는 나무의 길이 M이 주어진다. (1 ≤ N ≤ 1,000,000, 1 ≤ M ≤ 2,000,000,000) 둘째 줄에는 나무의 높이가 주어진다. 나무의 높이의 합은 항상 M보

www.acmicpc.net

문제 요약:

숫자 배열이 주어지고 특정 수보다 큰 수들과의 차이의 합이 정해진 m보다 커지는 수중 가장 큰수를 구하여라

실버2

 

소요시간:

~

 

1차 접근 :

먼저 m의 범위를 보고 2진탐색을 해야겠다고 생각한 뒤,  중간값을 정하고 이진탐색을 진행했다.

from bisect import bisect_left
import sys
input = sys.stdin.readline

n,k = map(int,input().split())
arr = list(map(int,input().split()))
arr.sort()

s = 0 
e = arr[-1]

while s<e:
	m = (s+e)//2
	idx = bisect_left(arr,m)
	
	new = 0
	for i in range(idx,len(arr)):
		new += arr[i]-m
	#print(s,m,e,new)
	if new==k :
		print(m)
		break
	if new >k :
		s = m+1
	if new <k :
		e = m-1

else:
	print(m-1)

실패 했으며, 작성하면서도 근사치 까지 갔을때 무엇이 최소값이 되는지 정하는것이 잘 안 됐다.

 

답 확인:

from bisect import bisect_left
import sys
input = sys.stdin.readline

n,k = map(int,input().split())
arr = list(map(int,input().split()))
arr.sort()

s = 0 
e = arr[-1]

while s<=e: #바뀐부분
	m = (s+e)//2
	idx = bisect_left(arr,m)
	
	new = 0
	for i in range(idx,len(arr)):
		new += arr[i]-m

	if new <k : #왼쪽탐색
		e = m-1
	else:		#오른쪽탐색
		result = m #최대한 덜 잘랐을때가 정답
		s = m+1

print(result)

오른쪽 탐색할 때 그 m값이 최대한 덜잘랐을 때 이므로 그 때 최신화를 해준다.

'코딩테스트 > 이진 탐색' 카테고리의 다른 글

[코테] 공유기 설치  (0) 2024.09.11
두 용액  (1) 2023.10.17
가장 긴 바이토닉 부분 수열  (0) 2023.10.07
징검다리 건너기  (0) 2023.07.05
bisect_left, bisect_right 구현  (0) 2023.06.07

관련글 더보기