Baekjoon

백준 2110번 공유기 설치 (Java)

백엔드 규니 2021. 1. 27. 23:10
728x90
반응형

문제 링크는 여기이고 풀이에 대해서 정리를 해보겠습니다. 

 

 

문제를 보았을 때, 집의 좌표가 10억까지 가능한 것을 볼 수 있습니다. 굉장히 큰 값이라 그냥 탐색으로는 안될 거 같고 이진탐색으로 해결을 해야 할 것 같습니다. 

 

 

1. 입력 받기

 

처음에 입력은 정렬된 순서로 주지 않기 때문에 정렬을 해서 위와 같이 만들었습니다. 그리고 우리가 구해야할 것은 공유기를 설치할 수 있는 집 사이의 최대 거리이기 때문에 이진탐색으로 조건을 걸어서 탐색을 해보겠습니다. 

  • 집 사이의 최대거리는 9 - 1 = 8 입니다.
  • 집 사이의 최소거리는 2 - 1 = 1 입니다.

 

위의 경우라면 집마다 거리가 1 ~ 8 사이일 것이고, 각 거리들 마다 문제에서 준 공유기의 개수만큼 설치할 수 있는지 여부를 판단해야 합니다. 

 

그러면 최대 Gap = 8, 최소 Gap = 1, 중간 Gap = 4로 정의할 수 있습니다. 즉, 집마다 거리를 4이상으로 놓고 공유기를 설치하면 위와 같이 설치할 수 있습니다. 하지만 입력 예시에서는 공유기 개수를 3으로 줬기 때문에 위의 경우는 불가능합니다.  중간 값이 4로 설치 가능한 공유기의 개수가 C보다 작으므로, Gap의 값을 감소시키면 됩니다. 

 

그래서 이번에는 최대 Gap = 3, 최소 Gap = 1, 중간 Gap = 2로 설정하겠습니다. 

 

그리고 집 마다 공유기 설치 거리를 2이상으로 놓고 설치를 해보니 3개를 설치할 수 있습니다. 즉, C(공유기 설치 개수)와 같기 때문에 가능합니다. 하지만 우리는 공유기를 설치할 수 있는 최대 거리를 찾아야 하기 때문에 일단 거리 2를 저장해놓고 더 큰 거리에서 가능한지 확인해보겠습니다. 

 

이번에는 최소 거리를 3, 최대 거리 3, 중간거리 3으로 집마다 거리를 3이상으로 놓고 공유기 설치를 해보겠습니다. 

 

거리를 3이상으로 놓아도 위와 같이 공유기를 C개 이상으로 설치할 수 있습니다. 즉, 거리가 2보다는 3일 때 최대이기 때문에 답은 3이 됩니다. 

 

 

구현 코드(Java)

import java.util.Arrays;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);

        int N = input.nextInt();  // 집의 개수
        int C = input.nextInt();  // 공유기의 개수
        int[] homeList = new int[N + 1];

        for (int i = 1; i <= N; ++i) {
            homeList[i] = input.nextInt();
        }

        Arrays.sort(homeList);   // 정렬

        int maxResult = 0;

        int left = 1;
        int right = homeList[N] - homeList[1];
        int d = 0;
        int ans = 0;

        while (left <= right) {
            int mid = (left + right) / 2;
            int start = homeList[1];
            int count = 1;  // 공유기 설치 GAP 저장
            for (int i = 1; i <= N; ++i) {
                d = homeList[i] - start;  // 집마다 거리 체크
                if (d >= mid) {  // 공유기 설치 가능한지 여부 체크
                    count++;
                    start = homeList[i]; // 설치 했다면 여기 집 부터 다시 거리 체크
                }
            }

            if (count >= C) {
                ans = mid;
                left = mid + 1;  // 더 많은 Gap에서 공유기 설치할 수 있는지 여부 확인
            } else {
                right = mid - 1; // 더 적은 Gap에서 공유기 설치할 수 있는지 여부 확인
            }
        }

        System.out.println(ans);
    }
}

 

반응형