공유기 설치
09 September 2019
문제 : https://www.acmicpc.net/problem/2110
이번은 이분 탐색을 응용하여 최솟값이나 최댓값을 찾는 문제를 풀어보도록 하겠습니다.
#include<stdio.h>
static int N, C;
static long long* arr;
void mergeSort(long long arr[], int l, int r);
long long binarySearch();
int main(void) {
scanf("%d %d", &N, &C);
arr = new long long[N];
for (int i = 0; i < N; i++)
{
scanf("%lld", &arr[i]);
}
mergeSort(arr, 0, N - 1);
printf("%lld\n", binarySearch());
return 0;
}
long long binarySearch() {
long long left = 0;
long long right = arr[N - 1];
long long ret = 0;
while (right >= left)
{
long long mid = (right + left) / 2;
long long start = arr[0];
int count = 1;
for (int i = 1; i < N; i++)
{
if (arr[i] - start >= mid)
{
count++;
start = arr[i];
}
}
if (count >= C)
{
ret = mid;
left = mid+1;
}
else {
right = mid - 1;
}
}
return ret;
}
void merge(long long arr[], int l, int m, int r)
{
int i, j, k;
int n1 = m - l + 1;
int n2 = r - m;
long long* L = new long long[n1];
long long* R = new long long[n2];
for (i = 0; i < n1; i++)
L[i] = arr[l + i];
for (j = 0; j < n2; j++)
R[j] = arr[m + 1 + j];
i = 0;
j = 0;
k = l;
while (i < n1 && j < n2)
{
if (L[i] <= R[j])
{
arr[k] = L[i];
i++;
}
else
{
arr[k] = R[j];
j++;
}
k++;
}
while (i < n1)
{
arr[k] = L[i];
i++;
k++;
}
while (j < n2)
{
arr[k] = R[j];
j++;
k++;
}
}
void mergeSort(long long arr[], int l, int r)
{
if (l < r)
{
int m = l + (r - l) / 2;
mergeSort(arr, l, m);
mergeSort(arr, m + 1, r);
merge(arr, l, m, r);
}
}
정해진 갯수의 공유기를 설치할 때 가장 긴 최소의 값을 구하는 문제입니다.이분탐색으로 최소 0 부터 최대 가장 먼 좌표의 값 중에서 탐색을 하여, 공유기의 갯수의 조건에 부합하는 값을 찾도록 합니다.
이분 탐색을 하여, 해당 공유기의 갯수가 적으면 공유기 간의 길이가 긴 것이니 최대 값을 내리고,
해당 공유기의 갯수가 많으면 공유기 간의 길이가 짧은 것이니 최소 값을 올려주도록 합니다.
해당 값을 이분 탐색으로 조회하고 마지막 값을 return해주도록 합니다.