입력 | 출력 |
---|---|
5 3 1 2 8 4 9 | 3 |
: 숫자가 커서 이분 탐색을 쓴다는 건 알겠는데 어떻게 적용해야 할 지를 모르겠다.
인접한 두 공유기 사이의 최대 거리를 구해야한다. ---> 인접한 두 공유기 사이의 최대 거리를 이분탐색으로 짐작한다.
- start = 1, end = 첫번째와 마지막 집의 거리 차이(최대)
- mid = (start+end)//2
- 무조건 첫번째 집에는 공유기를 설치해야한다.(가장 인접한 두 공유기 사이의 거리를 최대한 크게 하기 위해)
- 첫번째 집의 위치와 거리(mid)를 더한 값보다 큰 위치의 개수를 센다. 이 때 더한 값보다 큰 위치에 공유기를 설치하여 now값을 업데이트한다. 이후 새로 설치한 공유기에서 거리를 더한 값보다 큰 위치의 개수를 이어서 센다.
- for문이 끝난 후 개수가 설치하려는 공유기보다 많을 경우, 거리를 넓혀야하므로 start값을 mid+1로 업데이트. 개수가 설치하려는 공유기보다 적을 경우, 거리를 줄여야하므로 end값을 mid-1로 업데이트.
import sys
n, c = map(int, sys.stdin.readlin().split())
home = []
for _ in range(n):
home.append(int(sys.stdin.readlin()))
home.sort() # 이분탐색을 위한 정렬
ans = 0
s = 1
e = home[-1]-home[0] # 첫번째 집과 마지막 집 사이의 거리 = 최대 거리
while s<=e:
# 인접한 두 공유기 사이의 최대 거리가 mid라면
mid = (s+e)//2
# 첫번째 집에 설치
now = home[0]
cnt = 1
# 거리가 mid이상 차이 나는 것들을 세어준다.
for i in range(1, n):
if home[i] >= now + mid:
cnt += 1
now = home[i] # 공유기 설치
if cnt >= c: # c개 이상의 공유기를 설치할 수 있는 경우
ans = mid
s = mid+1 # 설치하려는 공유기보다 많으면 거리를 넓혀줘야
elif cnt < c: # 설치하려는 공유기보다 적으면 거리를 줄여야
e = mid-1
print(ans)