도현이의 집 N개가 수직선 위에 있다. 각각의 집의 좌표는 x1, ..., xN이고, 집 여러개가 같은 좌표를 가지는 일은 없다.
도현이는 언제 어디서나 와이파이를 즐기기 위해서 집에 공유기 C개를 설치하려고 한다. 최대한 많은 곳에서 와이파이를 사용하려고 하기 때문에, 한 집에는 공유기를 하나만 설치할 수 있고, 가장 인접한 두 공유기 사이의 거리를 가능한 크게 하여 설치하려고 한다.
C개의 공유기를 N개의 집에 적당히 설치해서, 가장 인접한 두 공유기 사이의 거리를 최대로 하는 프로그램을 작성하시오.
입력
첫째 줄에 집의 개수 N (2 ≤ N ≤ 200,000)과 공유기의 개수 C (2 ≤ C ≤ N)이 하나 이상의 빈 칸을 사이에 두고 주어진다. 둘째 줄부터 N개의 줄에는 집의 좌표를 나타내는 xi (0 ≤ xi ≤ 1,000,000,000)가 한 줄에 하나씩 주어진다.
출력
첫째 줄에 가장 인접한 두 공유기 사이의 최대 거리를 출력한다.
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException{
// TODO Auto-generated method stub
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken());
int c = Integer.parseInt(st.nextToken());
ArrayList<Integer> arr = new ArrayList<>();
for(int i = 0; i < n ; i++ ){
arr.add(Integer.parseInt(br.readLine()));
}
// 이진탐색을 위한 정렬
Collections.sort(arr);
int start = 1; // 가능한 최소거리
int end = arr.get(n-1) - arr.get(0); //가능한 최대거리
int result = 0;
while(start <= end){
int mid = (start + end) / 2;
// 처음 집에 공유기 무조건 설치.
int value = arr.get(0);
int cnt = 1; // 공유기 설치 횟수
for(int i = 1 ; i < n; i++ ){
if(arr.get(i) >= value + mid){
value = arr.get(i);
cnt++;
}
}
// 공유기 설치 횟수가 c 보다 크거나 같다면 거리를 늘려주기
if(cnt >= c){
start = mid +1;
result = mid;
}else{
end = mid -1;
}
}
System.out.println(result);
}
}
공유기 설치 문제는 나에겐 좀 어려웠던 문제였던거 같다... 문제가 잘이해가 되지않았다. 내가이해했던 건 집들이 있다면 바로 옆에있는 집만 신경쓰면 된다고 생각했다. 하지만 함정에 빠져들었을 뿐...;;
문제해결방법은 이러하다. 첫집에 공유기를 무조건 설치하고 시작한다. 기준점이 있어야하기 때문이다. 집이있다면 그 거리안엔 공유기를 설치할 필요가없다. 또한 공유기를 무조건 N 개 설치해야하기 때문에 두가지를 생각하고 풀어야한다.
공유기와 공유기 사이의 최소거리를 mid 라고 생각하고 풀면된다. 그 mid 값을 비교하면서 공유기가 닿을 수 있는거리를 파악하고 공유기를 설치하고를 반복하다 공유기 설치횟수가 설치횟수보가 크거나 같으면 start 를 늘려서 진행해주고 아니라면 end 값을 늘려서 진행해준다.