Kangho_Story

[백준] 11286번 절댓값 힙 C++ 풀이 본문

PS

[백준] 11286번 절댓값 힙 C++ 풀이

캉호 2024. 8. 1. 15:06
728x90
반응형
18
1
-1
0
0
0
1
1
-1
-1
2
-2
0
0
0
0
0
0
0​

알고리즘 분류

  • 자료 구조
  • 우선순위 큐

문제 설명

절댓값 힙은 다음과 같은 연산을 지원하는 자료구조이다.

  1. 배열에 정수 x (x ≠ 0)를 넣는다.
  2. 배열에서 절댓값이 가장 작은 값을 출력하고, 그 값을 배열에서 제거한다. 절댓값이 가장 작은 값이 여러 개일 때는, 가장 작은 수를 출력하고, 그 값을 배열에서 제거한다.

프로그램은 처음에 비어있는 배열에서 시작하게 된다.


입력 설명

첫째 줄에 연산의 개수 N(1≤N≤100,000)이 주어진다. 다음 N개의 줄에는 연산에 대한 정보를 나타내는 정수 x가 주어진다. 만약 x가 0이 아니라면 배열에 x라는 값을 넣는(추가하는) 연산이고, x가 0이라면 배열에서 절댓값이 가장 작은 값을 출력하고 그 값을 배열에서 제거하는 경우이다. 입력되는 정수는 -231보다 크고, 231보다 작다.


출력 설명

입력에서 0이 주어진 회수만큼 답을 출력한다. 만약 배열이 비어 있는 경우인데 절댓값이 가장 작은 값을 출력하라고 한 경우에는 0을 출력하면 된다.


예제 입력

18
1
-1
0
0
0
1
1
-1
-1
2
-2
0
0
0
0
0
0
0

예제 출력

-1
1
0
-1
-1
1
1
-2
2
0

아이디어

양수를 저장하는 오름차순 멀티맵, 음수를 저장하는 내림차순 멀티맵을 선언하여 값을 입력받는다.

0이 아닌 값이 입력으로 들어오면 음수 양수를 판별하여 각 멀티맵에 insert()한다.

0이 입력으로 들어오면 두개의 멀티맵의 begin()의 값을 비교하여 절댓값이 더 작은 값을 출력한다.

절댓값이 같다면 더 작은 값을 출력한다.


알고리즘

양수를 저장하는 오름차순 멀티맵, 음수를 저장하는 내림차순 멀티맵을 선언하여 값을 입력받는다.

0이 아닌 값이 입력으로 들어오면 음수 양수를 판별하여 각 멀티맵에 insert()한다.

0이 입력으로 들어오면 두개의 멀티맵 중 빈 곳이 있는지 판별하여 한 곳이 비었다면 남은 한 곳의 begin()을 출력한다.

모두 비었다면 0을 출력하고 어느 곳도 빈 곳이 없다면 두 개의 멀티맵의 begin()의 값을 비교하여 절댓값이 더 작은 값을 출력한다.

절댓값이 같다면 더 작은 값을 출력한다.


코드

#include <iostream>
#include <map>
using namespace std;
void func(multimap<int,int> &mpp, multimap<int,int,greater<int>> &mpm, int cmd)
{
    if(cmd == 0)
    {
        int m=0, p=0;
        if(!mpm.empty()) m = mpm.begin()->first;
        if(!mpp.empty()) p = mpp.begin()->first;
        if(!mpm.empty() && !mpp.empty())
        {
            if(-1*m <= p)
                {
                    cout<<m<<"\n";
                    mpm.erase(mpm.find(m));
                }
            else
                {
                    cout<<p<<"\n";
                    mpp.erase(mpp.find(p));
                }
        }
        else if(!mpp.empty())
        {
            cout<<p<<"\n";
            mpp.erase(mpp.find(p));
        }
        else if(!mpm.empty())
        {
            cout<<m<<"\n";
            mpm.erase(mpm.find(m));
        }
        else cout<<"0\n";
    }
    else
    {
        if(cmd < 0) mpm.insert({cmd,0});
        else mpp.insert({cmd,0});
    }
}
int main() {
    ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
    int n,cmd;
    multimap<int,int,greater<int>> mpm;
    multimap<int,int> mpp;
    cin>>n;
    while(n--)
        {
            cin>>cmd;
            func(mpp, mpm, cmd);
        }
    return 0;
}

후기

문제 링크 -> https://www.acmicpc.net/problem/11286

문제를 잘못읽어서 음수멀티맵과 양수멀티맵을 모두 오름차순으로 정렬해서 틀렸다.

-> 음수 멀티맵에 생성 시에 greater를 줘서 내림차순으로 변경

multimap에서 erase를 하면 같은 값을 모두 삭제하는 걸 몰라서 틀렸다.

-> 그냥 erase(key)를 하지말고 erase(find(key))를 하면 중복 키값 중 하나만 삭제한다.


본 블로그의 모든 글은 개인적인 학습 내용이므로 다양한 오류가 있을 수 있습니다.

오류를 발견하신다면 해당 내용 댓글로 알려주시면 감사하겠습니다!

728x90
반응형
Comments