자료구조 & 알고리즘/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. 포인트

  1. 아주 큰수의 범위가 주어질때는 이진탐색을 고려해보자
  2. 이진탐색의 개념과 구현을 잘 기억해 놓자
    • 최대 , 최소 값을 설정하고 중간값과 비교하여 최대 값과 최소값을 중간값 이후 이전 값으로 갱신해나가는 탐색

 

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)