728x90
🔗 문제 링크
2512번: 예산
첫째 줄에는 지방의 수를 의미하는 정수 N이 주어진다. N은 3 이상 10,000 이하이다. 다음 줄에는 각 지방의 예산요청을 표현하는 N개의 정수가 빈칸을 사이에 두고 주어진다. 이 값들은 모두 1 이상
www.acmicpc.net
💡 문제 풀이 및 해석
처음에는 평균을 잡아놓고, 평균 아래의 가격과의 차액을 더하는 방식으로 할려 했지만, 차액을 더하는 도중에 평균보다 위였던 금액이 평균보다 낮아져 버릴 수도 있음을 알았다. 그래서 차라리 이분탐색으로 금액을 정해놓고 이 금액이 가능한지 판별하는 방식으로 접근하기로 했다.
- 만약
전체 금액 <= 예산
인 경우 전체 금액을 모두 준다. - 이분탐색으로 지불할 최대 예산을 정한다.
- 예산이 가능한지 판단하는 방식은 전부 더하는 방식으로 한다.
3-1. 예산 <= 평균 인 경우는 예산을 더해준다.
3-2. 예산 < 평균 인 경우는 평균을 더해준다. - 결과를 출력한다.
⭐️ 정답 코드 및 설명
#include<iostream>
#include<vector>
using namespace std;
int N, maxCost;
int sum = 0;
int Max = 0;
vector<int> country;
void input() {
cin >> N;
country = vector<int>(N);
for (int i = 0; i < N; i++) {
cin >> country[i];
sum += country[i];
Max = max(Max, country[i]);
}
cin >> maxCost;
}
bool isCan(int mid) {
int cost = 0;
for (int cash : country) {
if (cash <= mid) cost += cash;
else cost += mid;
}
if (cost <= maxCost) return true;
else return false;
}
/*
int sol() {
int left = 0, right = maxCost;
while (left <= right) {
int mid = (left + right) / 2;
if (isCan(mid)) left = mid + 1;
else right = mid - 1;
}
return right;
}
*/
int sol() {
int left = 0, right = maxCost;
while (left < right) {
int mid = (left + right) / 2;
if (isCan(mid)) left = mid + 1;
else right = mid;
}
return left - 1;
}
int main() {
input();
if (sum <= maxCost) {
cout << Max;
return 0;
}
cout << sol();
return 0;
}
🤔 문제 후기
처음부터 단위가 큰 것을 보고 이분탐색을 생각했어야 했는데, 일단 그리디한 방식으로 접근을 했었다. 이런저런 생각을 하다가 결국 이분탐색으로 접근을 했는데, 개인적으로 주석친 부분처럼 right를 반환하면서 풀어왔는데 이번에는 어쩌다보니? left - 1
을 return 하게 되었다... 나중에 이분탐색에 대해서도 더 공부를 해야겠다고 생각했다.
728x90
'문제풀이 > 알고리즘 문제 풀이' 카테고리의 다른 글
[ 백준 4485 ] 녹색 옷 입은 애가 젤다지? (C++) - 다익스트라 (0) | 2024.04.22 |
---|---|
[ 백준 2580 ] 스도쿠 (C++) - 백트래킹, DFS (1) | 2024.04.18 |
[ 백준 2109 ] 순회강연 (C++) - 그리디, 우선순위큐 (0) | 2024.04.17 |
[ 백준 2565 ] 전깃줄 (C++) - DP (0) | 2024.04.15 |
[ 백준 2343 ] 기타 레슨 (C++) - 이분 탐색 (0) | 2024.04.11 |