문제 요약
도현이의 집 N개가 수직선 위에 있다. 각각의 집의 좌표는 x1, ..., xN이고, 집 여러개가 같은 좌표를 가지는 일은 없다.
도현이는 언제 어디서나 와이파이를 즐기기 위해서 집에 공유기 C개를 설치하려고 한다. 최대한 많은 곳에서 와이파이를 사용하려고 하기 때문에, 한 집에는 공유기를 하나만 설치할 수 있고, 가장 인접한 두 공유기 사이의 거리를 가능한 크게 하여 설치하려고 한다.
C개의 공유기를 N개의 집에 적당히 설치해서, 가장 인접한 두 공유기 사이의 거리를 최대로 하는 프로그램을 작성하시오.
문제 분석
첫집에 무조건 공유기를 설치한다 가정하고, 공유기 거리를 이분탐색을 통해 지속적으로 갱신하며 설치 가능한 공유기 개수를 카운트한다.
코드
package Week17;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class BOJ_2110 {
static int N, C;
static int[] houses;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
C = Integer.parseInt(st.nextToken());
houses = new int[N];
for(int i = 0; i < N; i++){
houses[i] = Integer.parseInt(br.readLine());
}
Arrays.sort(houses);
// 이분탐색으로 적절한 거리값을 탐색한다.
// 탐색할 거리 범위 지정
// 최소범위값는 0
int minDistance = 0;
// 최대범위값는 가장 끝값 - 첫값
int maxDistance = houses[N-1] - houses[0];
int result = 0;
while(minDistance <= maxDistance){
int selectedDistance = (minDistance + maxDistance) / 2;
// 가장 첫 위치는 무조건 공유기를 설치한다.
int cnt = 1;
// 거리 계산을 위해 이전집을 저장한다.
int prevHouse = houses[0];
// 현재 탐색중인 거리 mid를 기준으로, 설치할 수 있는 집을 탐색
for(int i = 1; i < N; i++){
if(houses[i] - prevHouse >= selectedDistance){
cnt++;
prevHouse = houses[i];
}
}
/*
C를 찾았더라도 계속 탐색하는 이유:
처음 찾은 저 값이 꼭 최적의 해라는 보장이 없기 때문에,
전체 탐색한 후 지속해서 최적값을 갱신해준다.
*/
// 현재 설치 가능한 공유기 개수가 C개 이상이라면?
if(cnt >= C){
result = selectedDistance;
minDistance = selectedDistance + 1;
}
// 현재 설치 가능한 공유기 개수가 C개 미만이라면?
else {
maxDistance = selectedDistance - 1;
}
}
System.out.println(result);
}
}
정리
새로 배운 내용
없음
개선할 점
이분탐색을 진행할 때, 어떤 값을 찾아야 하는지 찾는데 애를 먹었다.
더 찾아볼만한 사항
이 코드는 좀 더 최적화가 불가능할까?
'알고리즘 풀이 > 백준' 카테고리의 다른 글
[Silver I] 카드 합체 놀이 - 15903 (Java) (0) | 2023.07.11 |
---|---|
[Silver I] 지름길 - 1446 (Java) (0) | 2023.07.11 |
[Gold V] A와 B 2 - 12919 (Java) (0) | 2023.07.05 |
[Silver IV] 점화식 - 13699 (JAVA) (0) | 2023.07.03 |
[Gold IV] 주난의 난(難) - 14497 (JAVA) (0) | 2023.07.01 |