✅ 이진탐색
요청 예산의 최댓값은 100,000이고 지방 수의 최댓값은 10,000이므로
예산을 하나씩 줄여가며 각 지방의 예산을 구한뒤 국가 예산의 총합을 넘는지 안넘는지 판별하려면 최악의 경우 너무 많은 연산을 해야한다.
따라서 상한액을 반씩 줄여가며 이진탐색으로 구현했다.
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
using namespace std;
int arr[10001], N, M, sum = 0;
int low, high, mid;
bool is_possible()
{
sum = 0;
for (int i = 0; i < N; i++)
{
if (arr[i] > mid)
sum += mid;
else
sum += arr[i];
}
// cout << "sum : " << sum << " high : " << high << " mid : " << mid << "\n";
if (sum <= M)
return true;
else return false;
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin >> N;
for (int i = 0; i < N; i++)
{
cin >> arr[i];
sum += arr[i];
}
cin >> M;
if (sum <= M) // 모든 요청이 배정될 수 있는 경우
{
cout << *max_element(arr, arr + N) << "\n";
return 0;
}
sort(arr, arr+N);
low = 1;
high = arr[N-1];
mid = (low + high) / 2;
while (low <= high) // high : 4, low : 4 일때 high(=mid)도 판별해봐야 하므로 < 가 아닌, <= 까지 반복문 수행
{
if (is_possible())
{
low = mid+1;
mid = (low + high) / 2;
}
else
{
high = mid-1;
mid = (low + high) / 2;
}
}
cout << high << "\n";
return 0;
}
선형완전탐색으로는 풀기 힘드므로 이진탐색을 떠올리는 것이 중요했고
언제까지 이진탐색을 수행할껀지 반복문의 조건을 실수할뻔 했었음
high : 4, low : 4 일때 high(=mid)도 판별해봐야 하므로 low < high 가 아닌, low <= high 까지 반복문 수행