https://www.acmicpc.net/problem/7662
7662번: 이중 우선순위 큐
입력 데이터는 표준입력을 사용한다. 입력은 T개의 테스트 데이터로 구성된다. 입력의 첫 번째 줄에는 입력 데이터의 수를 나타내는 정수 T가 주어진다. 각 테스트 데이터의 첫째 줄에는 Q에 적
www.acmicpc.net
---------------------------------------------------핵심 알고리즘--------------------------------------------
heap(priority_queue)
---------------------------------------------------풀이----------------------------------------------------
min heap과 max heap을 동시에 사용한다.
bool Q[]를 정의해 각 인덱스의 값이 유효한지를 저장한다.
예를 들어, min heap에서는 지워졌다고 해도, max heap에선 지워지지 않은 경우를 피하기 위해서이다.
1000ms에 통과할 수 있었다.
#define FASTIO ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <queue>
#include <cmath>
#include <stack>
#include <limits.h>
using namespace std;
struct cmp1{
bool operator()(pair<int,int> a, pair<int,int> b){
return a.first > b.first;
}
};
struct cmp2{
bool operator()(pair<int,int> a, pair<int,int> b){
return a.first < b.first;
}
};
// 유효한 값인지
bool Q[1'000'001];
// 우선순위 값, Q에서의 인덱스
priority_queue<pair<int,int>, vector<pair<int,int> >, cmp1> min_heap;
priority_queue<pair<int,int>, vector<pair<int,int> >, cmp2> max_heap;
int Q_idx = 0;
void init_all(){
while(!min_heap.empty()){
min_heap.pop();
}
while(!max_heap.empty()){
max_heap.pop();
}
Q_idx = 0;
}
int main(void){
FASTIO;
int T;
cin >> T;
for(int test_case = 1; test_case <= T; test_case++){
init_all();
int K;
cin >> K;
char op;
int n;
for(int i = 0; i < K; i++){
cin >> op >> n;
switch(op){
case 'D':
// Q에서 최댓값 삭제
if(n > 0){
pair<int,int> cur;
while(!max_heap.empty()){
cur = max_heap.top();
max_heap.pop();
if(Q[cur.second]){
// 유효하지 않은 값으로 만들고 종료
Q[cur.second] = false;
break;
}
}
}
// Q에서 최솟값 삭제
else{
pair<int,int> cur;
while(!min_heap.empty()){
cur = min_heap.top();
min_heap.pop();
if(Q[cur.second]){
// 유효하지 않은 값으로 만들고 종료
Q[cur.second] = false;
break;
}
}
}
break;
// n을 Q에 삽입
case 'I':
max_heap.push(make_pair(n, Q_idx));
min_heap.push(make_pair(n, Q_idx));
Q[Q_idx++] = true;
break;
}
}
while(!max_heap.empty() && !Q[max_heap.top().second]){
max_heap.pop();
}
while(!min_heap.empty() && !Q[min_heap.top().second]){
min_heap.pop();
}
if(max_heap.empty() || min_heap.empty()){
cout << "EMPTY\n";
}
else{
cout << max_heap.top().first << " " << min_heap.top().first << "\n";
}
}
return 0;
}
---------------------------------------------------후기----------------------------------------------------
deque, list 등 이것저것 사용해보고, array에서 upper_bound를 사용해 정렬하면서 저장하는 방식도 사용해봤으며,
heap 하나로 최대를 빠르게 찾고 모두 pop하면서 최소를 찾는 방식으로도 사용해봤으나,
전부 1%이하에서 시간초과가 발생했다.
그리고 min heap과 max heap을 사용하는 방식으로 바꿨을 때, segmentation fault가 발생했다.
결국 찾은 문제는 test case가 여러 개인데 각 변수 초기화를 제대로 안 해준 것이다. 그래서 init_all()함수를 만들어 초기화하자 정답으로 인정되었다.(1000ms)
**초기화 함수를 만들어 초기화하는 버릇을 들이자!
'알고리즘' 카테고리의 다른 글
[BOJ] 11399 ATM (0) | 2023.06.01 |
---|---|
[BOJ] 9095 1, 2, 3 더하기 (0) | 2023.06.01 |
[BOJ] 7576 토마토 (0) | 2023.06.01 |
[BOJ] 2630 색종이 만들기 (2) | 2023.06.01 |
[BOJ] 1931 회의실 배정 (0) | 2023.06.01 |