문제
https://www.acmicpc.net/problem/2696
문제 설명
중앙 값 구하기이다
이문제는 처음 시간초과를 겪은 뒤 방향을 바꾸었다 혼자 아이디가 떠오르지 않아서 다른분이 도음울 주셨다 우선 우큐문제이다.
현재 min, max우큐 두가지를 가지고 있다고 정한다
둘째 max우큐에 중앙값을 가지게 하되, min우큐에는 중앙값보다 큰값들을 가지고 있게한다
셋째 두가지 값들의 균형을 유지하도록한다
위의 경우를 토대로 비어있을 때는 mxq에 넣고 나머지 경우에는 두가지를 보면된다
만약 mxq.size() == mnq.size()가 같을 경우(다음 들어오는 수가 중앙 값의 후보가 된다) 현재 들어오는 값이 max.top보다 작으면 mxq에 넣고 그렇지 않고 크다면 mnq에는 넣는다
왜냐? mxq에는 중앙값이하의 값들을 유지, mnq에는 중앙값 이상의 값들을 유지하기 위해서이다.
(mxq.size() > mnq.size())의 경우에는 만약 현재 중앙값 후보보다 값이 더 크다면 그냥 바로 mnq에 넣으면된다 그런데 값이 더 작게된다면 mxq에 넣어야하는데 이미 mxq는 사이즈가 더 큰데 또 넣는다면 균형에 문제가 생기기때문에 top값을 mnq네 넣고 그 후에 mxq에 새로운 값을 넣는다
소스
#include <bits/stdc++.h>
using namespace std;
int t, n, s, e, mid;
int main() {
cin >> t;
while (t--)
{
cin >> n;
vector<int> v, ans;
int ansCnt = 0;
v.resize(n + 1);
for (int i = 1; i <= n; i++) cin >> v[i];
priority_queue<int, vector<int>> mxq; //중앙값이하들을 삽입
priority_queue<int, vector<int>, greater<int>> mnq; // 중앙값 이상들을 넣는다
for (int i = 1; i <= n; i++)
{
if ((int)mxq.size() == 0) mxq.push(v[i]);
else if (mxq.size() == mnq.size()) {
// 1 2가 있을 때 다음 들어오는 수가 중앙 값이다
//들어온 수가 현재 중앙값(mxq.top())보다 크다면 중앙값을 교체해주어야합니다.
if (v[i] > mxq.top()) {
mnq.push(v[i]);
mxq.push(mnq.top());
mnq.pop();
}
else {
mxq.push(v[i]);
}
}
else if (mxq.size() > mnq.size()) {
// 들어오는 값이 중앙 값보다 작으면 원래 mxq에 넣어야하는데 바로 넣으면 크기의 균형이 무너지게된다 그래서 현재 중앙값을 mnq에 넣고 현재 들어오는 값을 mxq에 넣는다
if (mxq.top() > v[i]) {
mnq.push(mxq.top());
mxq.pop();
mxq.push(v[i]);
}
else {
mnq.push(v[i]);
}
}
if (i % 2) {
ansCnt++;
ans.push_back(mxq.top());
}
}
cout << ansCnt << endl;
for (auto a : ans) cout << a << " ";
cout << endl;
}
return 0;
}
'알고리즘' 카테고리의 다른 글
1차원 격자(시뮬레이션, 비공풀이) (0) | 2021.12.08 |
---|---|
백준 가운데를 말해요 1655 (c++) (0) | 2021.12.07 |
ub가 떴다. (주의), tie문법, 장애물 치우기(bfs + dfs) (0) | 2021.12.06 |
신박한 부분문자열, 데브매칭 (0) | 2021.12.05 |
탈출 백준3055, multisourceBfs (0) | 2021.12.05 |