[BOJ] 2512번 | μ˜ˆμ‚° (C++)

2023. 9. 6. 22:00ㆍCoding Test/BOJ

πŸ”—λ¬Έμ œ λ³΄λŸ¬κ°€κΈ°
 

2512번: μ˜ˆμ‚°

첫째 μ€„μ—λŠ” μ§€λ°©μ˜ 수λ₯Ό μ˜λ―Έν•˜λŠ” μ •μˆ˜ N이 주어진닀. N은 3 이상 10,000 μ΄ν•˜μ΄λ‹€. λ‹€μŒ μ€„μ—λŠ” 각 μ§€λ°©μ˜ μ˜ˆμ‚°μš”μ²­μ„ ν‘œν˜„ν•˜λŠ” N개의 μ •μˆ˜κ°€ λΉˆμΉΈμ„ 사이에 두고 주어진닀. 이 값듀은 λͺ¨λ‘ 1 이상

www.acmicpc.net

 

πŸ§‘‍πŸ’»ν’€μ΄ κ³Όμ •

λ§€κ°œλ³€μˆ˜ νƒμƒ‰μœΌλ‘œ ν’€ 수 μžˆμŠ΅λ‹ˆλ‹€. μ €λŠ” λ‹€μŒκ³Ό 같이 ν’€μ—ˆμŠ΅λ‹ˆλ‹€.

  1. μž…λ ₯ 받은 μ˜ˆμ‚°λ“€μ„ μ˜€λ¦„μ°¨μˆœμœΌλ‘œ μ •λ ¬ν•©λ‹ˆλ‹€.
  2. μ˜ˆμ‚°λ“€μ˜ 합계가 M μ΄ν•˜λΌλ©΄, μ˜ˆμ‚°λ“€ 쀑 μ΅œλŒ“κ°’(λ°°μ—΄μ˜ λ§ˆμ§€λ§‰ κ°’)을 좜λ ₯ν•˜κ³  μ’…λ£Œν•©λ‹ˆλ‹€.
  3. 그게 μ•„λ‹ˆλΌλ©΄, μ΅œμ†Œ μ˜ˆμ‚°κ°’(1)κ³Ό μ΅œλŒ€ μ˜ˆμ‚°κ°’(λ°°μ—΄μ˜ λ§ˆμ§€λ§‰ κ°’)을 가지고 이뢄 탐색을 μ‹œμž‘ν•©λ‹ˆλ‹€.
    • "mid = (left + right) / 2" 값을 κ³„μ‚°ν•©λ‹ˆλ‹€.
    • μ˜ˆμ‚°μ˜ 총 합계λ₯Ό κ³„μ‚°ν•˜λ˜, mid 값보닀 큰 μ˜ˆμ‚°μ€ mid κ°’μœΌλ‘œ 합계에 λ”ν•©λ‹ˆλ‹€.
    • λ‹€ λ”ν•œ 총 합계가 M μ΄ν•˜λΌλ©΄, left = mid + 1을 ν•˜κ³  max(mid, 이전 mid)둜 κ°±μ‹ ν•©λ‹ˆλ‹€.
    • μ•„λ‹ˆλΌλ©΄, right = mid - 1을 μ μš©ν•©λ‹ˆλ‹€.
    • left > rightκ°€ 될 λ•ŒκΉŒμ§€ μœ„ 과정을 λ°˜λ³΅ν•©λ‹ˆλ‹€.

 

βœοΈμ†ŒμŠ€ μ½”λ“œ 및 κ²°κ³Ό

#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#define FAST_IO cout.tie(NULL); cin.tie(NULL); ios::sync_with_stdio(false);
using namespace std;
using uint32 = unsigned int;

int main()
{
	FAST_IO

	int N;
	cin >> N;

	vector<uint32> budgets(N);
	for (int i = 0; i < N; i++)
		cin >> budgets[i];

	sort(budgets.begin(), budgets.end());
	uint32 start = 1, last = budgets.back();
	
	uint32 M;
	cin >> M;

	if (accumulate(budgets.begin(), budgets.end(), 0) <= M)
	{
		cout << budgets.back();
		return 0;
	}


	uint32 answer = 0;
	while (start <= last)
	{
		uint32 mid = (start + last) / 2;
		uint32 money = 0;

		for (const auto& budget : budgets)
			money += (budget <= mid) ? budget : mid;

		if (money <= M)
		{
			start = mid + 1;
			answer = max(answer, mid);
		}
		else
			last = mid - 1;
	}

	cout << answer;
	return 0;
}

728x90
λ°˜μ‘ν˜•