ML/AI/SW Developer

BAEK1655 가운데를 말해요(C++)

1. 문제 설명

  • 문제 링크
    수빈이가 정수를 하나씩 부를때, 동생은 현재까지 부른 숫자의 중간값을 말해야한다.
조건
N은 1보다 크거나 같고, 100,000보다 작거나 같은 자연수이다. 그 다음 N줄에 걸쳐서 수빈이가 외치는 정수가 차례대로 주어진다. 정수는 -10,000보다 크거나 같고, 10,000보다 작거나 같다.

2. 풀이

  • priority_queue 라이브러리 활용
  • 두개의 큐를 이용해 중간 값을 Top에 오도록 만들자!

3. 코드

  • c++
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<queue>

using namespace std;

int N;
priority_queue<int, vector<int>, less<int>> max_pq;
priority_queue<int, vector<int>, greater<int>> min_pq;

void Input() {
	cin >> N;
}

void Solve() {
	// N 번동안 숫자 받기
	for (int i = 0; i < N; i++) {
		int num; // 숫자
		cin >> num; // 숫자 받기

		// max 큐 크기가 min 큐 크기 보다 크면, min에, 아니면 max에 값 넣기 (top에 중앙을 유지하기 위해)
		if (max_pq.size() > min_pq.size()) min_pq.push(num);
		else max_pq.push(num);

		// max 큐와 min 큐의 크기가 같고, 둘다 비어있지 않은 경우
		if (max_pq.empty() == false && min_pq.empty() == false) {
			// max_pq의 크기가 더 크면 min과 swap
				// 더 작은 값을 출력해 줘야하기 때문 (짝수의 경우)
			if (max_pq.top() > min_pq.top()) {
				int temp_max = max_pq.top();
				max_pq.pop();
				int temp_min = min_pq.top();
				min_pq.pop();

				max_pq.push(temp_min);
				min_pq.push(temp_max);
			}
		}
		cout << max_pq.top() << "\n";
	}
}

int main() {

	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);

	//1. 입력
	Input();

	//2. 풀이
	Solve();

	return 0;
}

4. 결과

  • 그냥 다 입력받아 정렬해도 될지도?
  • endl 보다 개행문자 출력해주는게 훨씬 빠르다?
    • 위 코드에서 개행문자 출력을 endl로 바꾸면 시간초과가 된다…
endl 은 출력시 버퍼를 비운다.
단순 개행 문자 출력은 버퍼를 비우지 않는다.

그렇기 때문에 매 출력시 마다 버퍼를 비우는 것이 시간적으로 손해가 있었던것 같다.
보통, 버퍼를 다 채우고 한번에 출력하는 것이 빠르다고 알려져있다.