알고리즘 문제 풀기
백준 2110: 공유기 설치 - javascript(이진탐색, 그리디)
Fo_rdang
2024. 8. 19. 15:46
반응형
문제 출처
https://www.acmicpc.net/problem/2110
정답 풀이
흠 이 문제의 입력값을 봐보자.
집의 개수는 무려 (2<=N <=200,000) 범위이고,
공유기의 개수는 (2<= C<=N) 범위이고,
집의 좌표는 (0<=I<=1,000,000,000) 범위이다.
엄청난 범위,,, 어떤 알고리즘이 생각나는가?
이진탐색 !!!
이진탐색은 어떤 값을 기준으로 탐색해나갈 것인가가 중요하다.
여기서는 `공유기 사이의 최대거리`를 기준으로 탐색하면 되겠다.
공유기 사이가 될 수 있는 범위는
(1이상 ~ 가장 마지막 집 - 가장 첫번째 집) 이 될 것이다.
아래 그림을 보면 이해가 쉽다.
정리하자면,
- 공유기 거리의 최솟값은 : 1
- 공유기 거리의 최댓값은 : 마지막 집 위치 - 첫번째 집 위치
이제 문제를 두 부분으로 나눠서 생각하면 된다.
- 공유기 최대 거리를 이진탐색으로 찾아나간다.
- 해당 공유기 거리가 최대 거리가 되는지 확인한다. (코드에서 check 함수)
정답 코드
const input = require('fs').readFileSync('/dev/stdin').toString().trim().split('\n');
const [n,m] = input.shift().split(' ').map(v => +v)
let arr = [];
for(let i=0; i<n; i++){
arr.push(Number(input[i]))
}
arr.sort((a,b) => a-b)
function solution(n,m, arr){
let start = 1
let end = arr[n-1] - arr[0]
while(start <= end){
let mid = parseInt((start + end)/2);
if(check(mid)){
start = mid +1
}else{
end = mid - 1
}
}
return end;
function check(num){
let prev = arr[0]
let cnt = 1
for(let i=1; i<n; i++){
if(prev + num <= arr[i]){
cnt++;
prev = arr[i]
if(cnt >= m) return true
}
}
return false;
}
}
console.log(solution(n,m,arr))
반응형