알고리즘/백준
[백준][C++] 16564: 히오스 프로게이머
KANTAM
2023. 10. 23. 23:40
문제
풀이
이분 탐색을 사용한다.
- 현재 만들 수 있는 최소 레벨은 입력받은 레벨 중 가장 낮은 레벨이다. 이 값을 start로 설정한다.
- 현재 만들 수 있는 최대 레벨은 입력받은 레벨 중 가장 높은 레벨 + K이다. 이 값을 end로 설정한다.
- mid = (start + end) / 2로 설정한다.
- mid보다 낮은 레벨들을 mid까지 올렸을 때 필요한 레벨이 K 이하일 경우 정답을 갱신하고, start를 mid + 1로 변경한다.
- 초과일 경우 end를 mid - 1로 변경한다.
코드
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> levels;
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(nullptr);
int N, K;
int answer = 0;
cin >> N >> K;
for (int i = 0; i < N; ++i)
{
int level;
cin >> level;
levels.push_back(level);
}
// 입력받은 레벨을 정렬한다.
sort(levels.begin(), levels.end());
// 현재 만들 수 있는 최소 레벨인 levels[0]이 start가 된다.
int start = levels[0];
// 현재 만들 수 있는 최대 레벨인 levels[N - 1] + k가 end가 된다.
int end = levels[N - 1] + K;
while (start <= end)
{
// mid까지 레벨을 올렸을 경우를 검사한다.
int mid = (start + end) / 2;
// 레벨을 mid까지 올릴 때까지 필요한 레벨의 총합
long long need_levels = 0;
for (int i = 0; i < N; ++i)
{
int need_level = mid - levels[i];
if (need_level > 0)
{
need_levels += need_level;
}
}
// 올려여할 레벨이 K보다 적다면 올려야할 레벨을 증가시킨다.
if (need_levels <= K)
{
answer = max(answer, mid);
start = mid + 1;
}
else
{
end = mid - 1;
}
}
cout << answer;
return 0;
}