반응형
문제 링크 : 1655번: 가운데를 말해요 (acmicpc.net)
1655번: 가운데를 말해요
첫째 줄에는 수빈이가 외치는 정수의 개수 N이 주어진다. N은 1보다 크거나 같고, 100,000보다 작거나 같은 자연수이다. 그 다음 N줄에 걸쳐서 수빈이가 외치는 정수가 차례대로 주어진다. 정수는 -1
www.acmicpc.net

> 풀이
입력을 한 번 받을 때마다 정렬을 하여 중간값을 찾아야 한다.
보통의 정렬을 쓰게되면 복잡도가 n x nlogn이 되는데 무조건 시간초과가 날 것 같다.
따라서 삽입 복잡도가 logn인 우선순위 큐를 쓰자
우선순위 큐를 하나만 쓸 경우 중간값을 찾기 힘들다. 따라서 최대힙, 최소힙 하나씩 두 개의 우선순위 큐를 써서 중간값을 찾도록 하자
최대힙 | 최소힙 순으로 두고 두 우선순위 큐의 개수를 같게 유지하면 중간값을 쉽게 찾을 수 있다
#include <bits/stdc++.h>
using namespace std;
priority_queue<int, vector<int>, less<int> > pq1;
priority_queue<int, vector<int>, greater<int> > pq2;
int N, n;
int main(void)
{
scanf("%d", &N);
for (int i = 0; i < N; i++) {
scanf("%d", &n);
if (i == 0) {
pq1.push(n);
printf("%d\n", n);
continue;
}
else if (pq2.size() == 0) {
if (pq1.top() <= n) pq2.push(n);
else {
int tmp = pq1.top();
pq1.pop();
pq1.push(n);
pq2.push(tmp);
}
printf("%d\n", pq1.top());
continue;
}
int m1 = pq1.top(), m2 = pq2.top();
int s1 = pq1.size(), s2 = pq2.size();
if (n >= m1 && n <= m2) {
if (s1 == s2) {
pq1.push(n);
}
else if (s1 > s2) {
pq2.push(n);
}
}
else if (n < m1) {
if (s1 == s2) {
pq1.push(n);
}
else if (s1 > s2) {
int tmp = pq1.top();
pq1.pop();
pq1.push(n);
pq2.push(tmp);
}
}
else {// n > m2
if (s1 == s2) {
int tmp = pq2.top();
pq2.pop();
pq2.push(n);
pq1.push(tmp);
}
else if (s1 > s2) {
pq2.push(n);
}
}
printf("%d\n", pq1.top());
}
return 0;
}반응형
'알고리즘 (백준) > BOJ 길라잡이 (1)' 카테고리의 다른 글
| 백준 1826 (연료 채우기) / C++ (0) | 2021.05.22 |
|---|---|
| 백준 13305 (주유소) / C++ (0) | 2021.05.20 |
| 백준 1715 (카드 정렬하기) / C++ (0) | 2021.05.14 |
| 백준 2805 (나무 자르기) / C++ (0) | 2021.05.13 |
| 백준 2512 (예산) / C++ (0) | 2021.05.12 |