문제 링크
https://www.acmicpc.net/problem/1655
풀이 아이디어
이 문제는 오직 '가운데' 에 무엇이 있냐만 관심이 있는 문제이다.
만약 이 문제를 입력이 들어올때마다 정렬해서 가운데 인덱스의 원소를 출력하려고 하면 nlogn의 시간이 걸린다.
1부터 100000까지의 입력이 들어온다고 가정할때 합치면 약 1700초의 시간이 걸리는 무식한 방법이므로 이 방법은 쓸 수 없다.
즉 아예 들어올때마다 '정렬'을 통해서 무언가를 하려고 하면 안된다는 사실을 먼저 인지하자.
이 문제는 nlogn의 구원자, priority queue를 2개를 활용하면 풀 수 있다.
minQ와 maxQ 두 개의 priority queue를 우선 준비한다.
N개의 원소가 있고 그 중 n개의 숫자까지 진행되었다고 가정했을때,
minQ에는 크기별로 0~mid의 작은 원소들이, maxQ에는 mid+1~n 의 큰 원소들이 들어가는 우선순위 큐이다.
즉 minQ의 가장 큰 수 는 maxQ의 가장 작은 수보다 작아야 된다.
이를 구현하려면 minQ는 가장 큰 수가 top()에 위치하도록 cmp 인자를 less<int>로 주고,
반대로 maxQ는 가장 작은 수가 top()에 위치하도록 greater<int> 로 인자를 준다.
그 후는 간단하다. minQ - maxQ - minQ - maxQ -... 의 패턴으로 원소가 들어오도록 for문을 돌린 후,
minQ의 최댓값과 maxQ의 최솟값의 대소관계를 비교하면서 대소관계가 역전될경우, top 원소를 바꾸기만 하면 된다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
#include <bits/stdc++.h>
using namespace std;
int N;
priority_queue<int,vector<int>,less<int>> minQ; //4321
priority_queue<int,vector<int>,greater<int>> maxQ; //1234
int main(void){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>N;
for(int i=0; i<N; i++) {
int num;
cin >> num;
if(minQ.size()==maxQ.size())
else
if(i==0)
else {
if (a > b) {
minQ.pop();
maxQ.pop();
}
}
}
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
'알고리즘 > 백준' 카테고리의 다른 글
백준 1972 놀라운 문자열 - substr로 해결못하는 문자열 처리 문제 (0) | 2020.06.29 |
---|---|
백준 2872 - 우리집엔 도서관이 있어 c (0) | 2020.04.23 |
백준 2206 벽부수고 이동하기 - 이제는 3차원 visited 배열이 필요하다. c++ (2) | 2020.04.07 |
백준 14500 테트로미노 - 모든게 다 dfs로 되는건 아니다 c++ (2) | 2020.04.04 |
백준 14888 - 연산자 끼워넣기 - 백트래킹 (C++) (0) | 2020.03.29 |