[BaekJoon] 2110번 : 공유기 설치
Updated:
2110번 : 공유기 설치
공유기를 c 개 설치하는 경우 가장 인접한 공유기의 거리의 최댓값을 구하면 된다.
가장 먼저 떠오르는 방법은 공유기 c 개를 설치하는 조합을 모두 구해 각자 공유기 사이의 거리의 최솟값을 구한다음 그 중 최댓값을 뽑으면 답을 구할 수 있다.
하지만 집의 개수는 최대 200,000 개 이기 때문에 이 방법으로는 절대 구할 수 없다.
따라서 가장 인접한 공유기 사이의 최대거리를 범위로 정해 이진탐색을 통해 찾아야 한다.
공유기를 3개 설치할 수 있고 [1, 2, 4, 8, 9] 의 위치에 있는 집 5개가 있다.
가장 인접한 공유기 사이의 최대거리는 1 ~ 8 이 될 것이다.
STEP 1
[1, 8] 의 중간 값인 4 를 가지고 공유기를 설치해 본다.
[1, 2, 4, 8, 9] 1, 4 번에만 설치를 할 수 있다.
공유기 사이의 거리를 4로 두었을 때 c 개보다 적게 설치 할 수 있다.
따라서 공유기 사이의 거리를 줄여볼 필요가 있다.
STEP 2
[1, 3] 의 중간 값인 2 를 가지고 공유기를 설치해 본다.
[1, 2, 4, 8, 9] 1, 4, 8 번에 설치를 할 수 있다.
c 개 이상의 공유기를 설치 할 수 있기 때문에 이번엔 공유기 사이의 거리를 늘려볼 필요가 있다.
STEP 3
[3, 3] 의 중간 값인 3 을 가지고 공유기를 설치해 본다.
[1, 2, 4, 8, 9] 1, 4, 8 번에 설치를 할 수 있다.
c 개 이상의 공유기를 설치 할 수 있기 때문에 공유기 사이의 거리를 늘려볼 필요가 있다.
STEP 4
[4, 3] start 의 값이 end 값 보다 커졌기 때문에 가장 인접한 공유기 사이의 최대거리는 STEP 3 에서 구한 3 임을 알 수 있다.
어떤 값을 이진 탐색의 범위로 잡고 풀어야 할지, 그 범위를 어떻게 갱신해 가며 답을 구해야 할지 정하는게 가장 어렵다..
def solution():
	answer = 0
	start = field[1] - field[0]
	end = field[-1] - field[0]
	while start <= end:
		mid = (start + end) // 2
		antenna = field[0]
		antenna_cnt = 1
		for i in range(1, n):
			if field[i] >= (antenna + mid):
				antenna = field[i]
				antenna_cnt += 1
		if antenna_cnt >= c:
			start = mid + 1
			answer = mid
		else:
			end = mid - 1
	return answer
if __name__ == '__main__':
	n, c = map(int, input().split())
	field = [int(input()) for _ in range(n)]
	field.sort()
	print(solution())
      
    
Leave a comment