자료구조 & 알고리즘/BOJ 문제풀이
[백준 2110] 공유기 설치 (python 풀이)
쉽코기
2021. 9. 21. 19:03
1. 문제
도현이의 집 N개가 수직선 위에 있다. 각각의 집의 좌표는 x1, ..., xN이고, 집 여러개가 같은 좌표를 가지는 일은 없다.
도현이는 언제 어디서나 와이파이를 즐기기 위해서 집에 공유기 C개를 설치하려고 한다. 최대한 많은 곳에서 와이파이를 사용하려고 하기 때문에, 한 집에는 공유기를 하나만 설치할 수 있고, 가장 인접한 두 공유기 사이의 거리를 가능한 크게 하여 설치하려고 한다.
C개의 공유기를 N개의 집에 적당히 설치해서, 가장 인접한 두 공유기 사이의 거리를 최대로 하는 프로그램을 작성하시오.
2. 입력
첫째 줄에 집의 개수 N (2 ≤ N ≤ 200,000)과 공유기의 개수 C (2 ≤ C ≤ N)이 하나 이상의 빈 칸을 사이에 두고 주어진다. 둘째 줄부터 N개의 줄에는 집의 좌표를 나타내는 xi (0 ≤ xi ≤ 1,000,000,000)가 한 줄에 하나씩 주어진다.
3. 출력
첫째 줄에 가장 인접한 두 공유기 사이의 최대 거리를 출력한다.
4. 포인트
- 아주 큰수의 범위가 주어질때는 이진탐색을 고려해보자
- 이진탐색의 개념과 구현을 잘 기억해 놓자
- 최대 , 최소 값을 설정하고 중간값과 비교하여 최대 값과 최소값을 중간값 이후 이전 값으로 갱신해나가는 탐색
4. 문제 풀이
문제 에서 N의 최대값은 20만 , x 의 최대값은 10 억이다. 위와 같은 아주 큰수의 범위가 주어졌을경우 이진탐색을 고려해보아야한다. 이진탐색의 경우 N*logX 로서 20만 * 약 30으로 2000만 보다 훨씬 작게된다.
문제의 핵심은 적절한 gap 값을 찾는 것이다. 적절한 gap 이상의 거리 도 있겠지만 기준이 되는 가장 작은 거리 인 gap을 찾아 도출하면 된다. gap 의 최저 후보와 최대 후보를 놓고 각각의 값을 middle 값으로 갱신해나가는 이진탐색으로 풀 수 있다.
# 공유기 설치
# 동적 계획법으로 풀어봅시당~
N ,C = map(int , input().split())
lst = []
for i in range(N):
lst.append(int(input()))
lst.sort()
gap_max = lst[-1] - lst[0]
gap_min = 1
result = 0
while gap_max >= gap_min :
mid = (gap_max + gap_min) // 2
intalled_value = lst[0]
count = 1
for i in range(1,len(lst)):
if lst[i] >= intalled_value + mid:
intalled_value = lst[i]
count += 1
if count >= C:
result = mid
gap_min = mid +1
else:
gap_max = mid -1
print(result)