개발/알고리즘
백준 7662번 : 이중 우선순위 큐
라사 RASA
2020. 8. 17. 19:44
문제 접근
최대 힙, 최소 힙 코드 응용해서 구현했는데 일단 테스트 케이스는 잘 돌아가고 제출 때 시간 초과가 나온다. 시간 복잡도를 계산해보니 insert 함수는 O(lgN) 인데, delete 함수는 find 함수로 인해 O(N) 이다. lower_bound() 사용 시 O(lgN) 에 찾을 수 있다고 해서 바꿔봤는데 시간 초과는 해결되어도 틀렸다고 나온다. 확인해보니 lower_bound() 는 정렬되어 있는 상태에서 목표값 n 보다 같거다 큰 원소의 주소를 반환하는 함수여서 정렬이 되어있어야 한다.
find() 함수를 직접 O(lgN) 으로 구현해보려고 했는데 방법이 없는 것 같다.
문제 코드 ( 시간 초과 )
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> maxheap;
vector<int> minheap;
// insert 함수의 시간 복잡도는 O(lgN)
void insert_maxheap(int n)
{
int cur = maxheap.size();
maxheap.push_back(n);
while(cur>0 && maxheap[cur]>maxheap[(cur-1)/2])
{
swap(maxheap[cur],maxheap[(cur-1)/2]);
cur=(cur-1)/2;
}
}
void insert_minheap(int n)
{
int cur = minheap.size();
minheap.push_back(n);
while(cur>0 && minheap[cur]<minheap[(cur-1)/2])
{
swap(minheap[cur],minheap[(cur-1)/2]);
cur=(cur-1)/2;
}
}
// delete 함수의 시간 복잡도는 O(N) -> find 함수의 시간 복잡도 O(N)
void delete_maxheap(int n)
{
int cur = lower_bound(maxheap.begin(), maxheap.end(), n) - maxheap.begin();
swap(maxheap[cur], maxheap[maxheap.size()-1]);
maxheap.pop_back();
while(maxheap.size()>cur*2+2)
{
if(maxheap[cur] > maxheap[cur*2+1] || maxheap[cur] > maxheap[cur*2+2])
break;
if(maxheap[cur*2+1] >= maxheap[cur*2+2])
{
swap(maxheap[cur], maxheap[cur*2+1]);
cur=cur*2+1;
}
else
{
swap(maxheap[cur], maxheap[cur*2+2]);
cur=cur*2+2;
}
}
if(maxheap.size()>cur*2+1)
{
if(maxheap[cur] < maxheap[cur*2+1])
swap(maxheap[cur], maxheap[cur*2+1]);
}
}
void delete_minheap(int n)
{
int cur = lower_bound(minheap.begin(), minheap.end(), n) - minheap.begin();
swap(minheap[cur], minheap[minheap.size()-1]);
minheap.pop_back();
while(minheap.size()>cur*2+2)
{
if(minheap[cur] < minheap[cur*2+1] || minheap[cur] < minheap[cur*2+2])
break;
if(minheap[cur*2+1] <= minheap[cur*2+2])
{
swap(minheap[cur], minheap[cur*2+1]);
cur=cur*2+1;
}
else
{
swap(minheap[cur], minheap[cur*2+2]);
cur=cur*2+2;
}
}
if(minheap.size()>cur*2+1)
{
if(minheap[cur] > minheap[cur*2+1])
swap(minheap[cur], minheap[cur*2+1]);
}
}
int main(void)
{
ios::sync_with_stdio(false);
cin.tie(NULL);
int T, k, n;
char com;
cin>>T;
while(T--)
{
maxheap.clear();
minheap.clear();
cin>>k;
while(k--)
{
cin>>com>>n;
if(com=='I')
{
insert_maxheap(n);
insert_minheap(n);
}
else if(com=='D')
{
if(n==1 && !maxheap.empty())
{
delete_minheap(maxheap[0]);
delete_maxheap(maxheap[0]);
}
else if(n==-1 && !maxheap.empty())
{
delete_maxheap(minheap[0]);
delete_minheap(minheap[0]);
}
}
}
if(maxheap.empty())
cout<<"EMPTY\n";
else
cout<<maxheap[0]<<' '<<minheap[0]<<'\n';
}
}
문제 코드 ( 맞았습니다. )
#include <iostream>
#include <map>
#include <algorithm>
using namespace std;
int main(void)
{
ios::sync_with_stdio(false);
cin.tie(NULL);
int T, k, n;
char com;
cin>>T;
while(T--)
{
map<int,int> heap;
cin>>k;
while(k--)
{
cin>>com>>n;
if(com=='I')
{
if(heap.find(n)==heap.end())
heap.insert(make_pair(n,0));
else
++heap[n];
}
else if(com=='D' && !heap.empty())
{
map<int,int>::iterator it;
if(n==1)
it = --heap.end();
else
it = heap.begin();
if(it->second==0)
heap.erase(it);
else
it->second--;
}
}
if(heap.empty())
cout<<"EMPTY\n";
else
cout<<(--heap.end())->first<<' '<<heap.begin()->first<<'\n';
}
}