가운데를 말해요 성공
0.1 초 (하단 참고) | 128 MB | 31624 | 9224 | 7027 | 31.115% |
문제
백준이는 동생에게 "가운데를 말해요" 게임을 가르쳐주고 있다. 백준이가 정수를 하나씩 외칠때마다 동생은 지금까지 백준이가 말한 수 중에서 중간값을 말해야 한다. 만약, 그동안 백준이가 외친 수의 개수가 짝수개라면 중간에 있는 두 수 중에서 작은 수를 말해야 한다.
예를 들어 백준이가 동생에게 1, 5, 2, 10, -99, 7, 5를 순서대로 외쳤다고 하면, 동생은 1, 1, 2, 2, 2, 2, 5를 차례대로 말해야 한다. 백준이가 외치는 수가 주어졌을 때, 동생이 말해야 하는 수를 구하는 프로그램을 작성하시오.
입력
첫째 줄에는 백준이가 외치는 정수의 개수 N이 주어진다. N은 1보다 크거나 같고, 100,000보다 작거나 같은 자연수이다. 그 다음 N줄에 걸쳐서 백준이가 외치는 정수가 차례대로 주어진다. 정수는 -10,000보다 크거나 같고, 10,000보다 작거나 같다.
출력
한 줄에 하나씩 N줄에 걸쳐 백준이의 동생이 말해야 하는 수를 순서대로 출력한다.
예제 입력 1 복사
7
1
5
2
10
-99
7
5
예제 출력 1 복사
1
1
2
2
2
2
5
시간 제한
- Python 3: 0.6 초
- PyPy3: 0.6 초
- Python 2: 0.6 초
- PyPy2: 0.6 초
보면알다시피 시간제한이 짧다.
처음엔 그래서
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
int main() {
int N;
cin >> N;
int num;
priority_queue<int, vector<int>, greater<int>> pq;
for (int i = 0; i < N; i++) {
cin >> num;
pq.push(num);
if (i < 2) {
cout << pq.top() << endl;
continue;
}
int size = pq.size();
vector<int> v;
if (pq.size() % 2 == 0) {
for (int i = 0; i < (size/ 2)-1; i++) {
v.push_back(pq.top());
pq.pop();
}
cout << pq.top() << endl;
for (int i = 0; i < v.size(); i++) {
pq.push(v[i]);
}
}
else if (pq.size() % 2 == 1) {
for (int i = 0; i < (size/ 2); i++) {
v.push_back(pq.top());
pq.pop();
}
cout << pq.top() << endl;
for (int i = 0; i < v.size(); i++) {
pq.push(v[i]);
}
}
}
return 0;
}
이렇게 짰는데
n^2정도시간이라 시간초과가 떴다.
#include <iostream>
#include <queue>
using namespace std;
int main() {
int N;
cin >> N;
int num;
priority_queue<int> max_pq;
priority_queue<int, vector<int>, greater<int>> min_pq;
for (int i = 0; i < N; i++) {
scanf("%d",&num);
if (min_pq.size() == max_pq.size())
max_pq.push(num);
else
min_pq.push(num);
if (max_pq.size() != 0 && min_pq.size() != 0 && max_pq.top() > min_pq.top()) {
int a = max_pq.top();
int b = min_pq.top();
max_pq.pop();
min_pq.pop();
max_pq.push(b);
min_pq.push(a);
}
printf("%d\n", max_pq.top());
}
return 0;
}
이건 그 이후 코드인데 우선순위 큐를 2개써서 들어온 값이 항상 max_pq의 top()에 자리하도록 만들었다.
처음엔 항상 max에 들어가고
다으엔 항상 min에 들어간다.
그리고 넣을때마다 맥스힙과 민힙을 보고 민힙의 top()이 맥스힙의 top()보다 크다면 위치를 바꿔준다.
그러면 항상 max힙에는 중간값이 들어간다.
'백준' 카테고리의 다른 글
백준 2667: 단지번호 붙이기 (0) | 2022.03.01 |
---|---|
백준 1260 : DFS와 BFS (0) | 2022.02.28 |
백준 12865 : 평범한 배낭 (0) | 2022.02.27 |
백준 9465: 스티커 (0) | 2022.02.16 |
백준 1904 : 01타일 (2) | 2022.02.16 |