$$\newcommand{\Z}{\mathbb{Z}} \newcommand{\R}{\mathbb{R}} \newcommand{\Q}{\mathbb{Q}} \newcommand{\N}{\mathbb{N}}\newcommand{\C}{\mathbb{C}} \newcommand{\oiv}[1]{\left] #1 \right[} \newcommand{\civ}[1]{\left[ #1 \right]} \newcommand{\ad}[1]{\text{ad}(#1)} \newcommand{\acc}[1]{\text{acc}(#1)} \newcommand{\Setcond}[2]{ \left\{\, #1 \mid #2 \, \right\}} \newcommand{\Set}[1]{ \left\{ #1 \right\}} \newcommand{\abs}[1]{ \left\lvert #1 \right\rvert}\newcommand{\norm}[1]{ \left\| #1 \right\|}\newcommand{\prt}{\mathcal{P}}\newcommand{\st}{\text{ such that }}\newcommand{\for}{\text{ for }} \newcommand{\cl}[1]{\text{cl}(#1)}\newcommand{\oiv}[1]{\left] #1 \right[}\newcommand{\interior}[1]{\text{int}(#1)}$$

BOJ 1655 가운데를 말해요::::Gratus' Blog

BOJ 1655 가운데를 말해요

알고리즘 문제풀이/BOJ 2019. 8. 18. 02:51

Running Median Algorithm 이라고 해서, 숫자들이 들어올 때마다 실시간으로 중앙값을 출력하는 알고리즘이 있다. 

대략 설명하자면, 두 개의 힙을 유지하는데, 이 두 힙은 작은 쪽 (small) 과 큰 쪽 (big) 을 나누어 반씩 저장한다. 

단, 이때 작은 쪽은 최대 힙을 이용하여 가장 큰 원소가 위에 올라오게, 큰 쪽은 최소 힙을 이용하여 가장 작은 원소가 위에 올라오게 처리한다.

새로운 원소가 들어올 때마다 일단 작은 쪽에 넣어 보고, 필요한 개수만큼 작은 쪽의 큰 원소들을 뽑아서 큰 쪽에 집어넣어 주면 항상 원소의 개수가 같거나 작은 쪽이 1개 많게 처리해 줄 수 있다.

 

만약 지금까지 들어온 수가 짝수개라면, 두 힙에는 같은 수의 원소가 들어 있게 된다. 이때 중앙값은 정의하기 나름인데, 가운데 두 수는 각각 small 힙의 최댓값과 big 힙의 최솟값으로 둘다 top을 통해서 확인할 수 있으므로, 두 원소의 산술평균을 내든 항상 작은걸 고르든 큰걸 고르든 랜덤하게 고르든 시키는 대로 하면 된다.

 

이 문제의 경우, 두 수 중 작은 것을 중앙값으로 정의하였으므로 항상 small 힙의 최댓값을 고르기로 하자.

 

지금까지 들어온 수가 홀수개라면, small 힙에 한 개가 더 들어가게 하면 된다. (사실 아무 쪽이든 상관은 없다)

그리고 중앙값은 small 힙의 top을 뽑아내면 된다.

...더보기
#include <bits/stdc++.h>
#define usecppio ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
using namespace std;

priority_queue<int> small;
priority_queue<int, vector <int>, greater<int>> big;
int main()
{
	usecppio
	int n;
	cin >> n;
	for (int i = 1; i<=n; i++)
	{
		int x;
		cin >> x;
		small.push(x);
		if (!(i%2))
		{
			big.push(small.top());
			small.pop();
		}
		while(!big.empty() && !small.empty() && (big.top()<small.top()))
		{
			int u = small.top();
			int v = big.top();
			small.pop();
			big.pop();
			small.push(v);
			big.push(u);
		}
		cout << small.top() << '\n';
	}
}

 

'알고리즘 문제풀이 > BOJ' 카테고리의 다른 글

BOJ 12972 GCD 테이블  (0) 2019.09.13
BOJ 900문제 달성!  (0) 2019.09.01
BOJ 1806 부분합  (0) 2019.08.11
BOJ 2515 전시장  (0) 2019.08.09
BOJ 3653 영화 수집  (1) 2019.07.30
admin