(C++) 백준 11286번 - 절대값 힙

코딩너구리·2025년 11월 7일

코딩 문제 풀이

목록 보기
71/266

https://www.acmicpc.net/problem/11286

문제

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

1) 배열에 정수 x (x ≠ 0)를 넣는다.
2) 배열에서 절댓값이 가장 작은 값을 출력하고, 그 값을 배열에서 제거한다. 
절댓값이 가장 작은 값이 여러개일 때는, 가장 작은 수를 출력하고, 그 값을 배열에서 제거한다.
> 프로그램은 처음에 비어있는 배열에서 시작하게 된다.

접근

우선순위 큐를 사용하여 조건의 연산을 구현한다.

문제해결

> 우선순위 큐에서 세번쨰 인수로 사용할 비교 함수객체인 cmp를 정의해준다. 
조건대로 abs를 통해 절대값을 구하고 절대값이 같다면 두 수 중에서 더 작은수가 우선순위가 높아 앞에오고, 
절대값이 다르면 절대값이 더 작은 값이 앞에온다.
> 우선순위 큐를 선언해준다. 세번째 인수로 앞서 정의한 cmp를넣어준다.
> 입력으로 0이 들어왔을 때와 아닐 때를 먼저 나눠주고
0일때 만약 큐가 비어있다면 0을 출력하고 안비어있으면 큐의 맨 앞에 있는 값을 출력하고 그 값을 제거한다.
> 0이 아니면 들어온 값을 push해서 큐에 넣어준다.

코드

#include <iostream>
#include <algorithm>
#include <queue>
#include <cmath>
using namespace std;

struct cmp
{
	bool operator()(int a, int b)
	{
		if (abs(a) == abs(b))
			return a > b;
		return abs(a) > abs(b);
	}
}; 
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);

	int N;
	cin >> N;
	priority_queue<int, vector<int>, cmp> pq;

	while(N--)
	{
		int t;
		cin >> t;
		if (t == 0)
		{
			if (pq.empty())
			{
				cout << 0 << '\n';
				continue;
			}
			cout << pq.top() << '\n';
			pq.pop();
			continue;
		}
		pq.push(t);
	}
}

후기

우선 순위 큐를 처음 다뤄봤다. 생각보다 까다롭다.
서번째 인자인 cmp는 sort와 다르게 "타입"이기 때문에 함수가 올 수 없다. 그래서 구조체나 클래스를 통해 정의해줘야한다. struct를 통해 일단 선언하고 operator를 통해 마치 함수처럼 쓸 수 있게 함수객체로 만들어준다.
그리고 내부 정렬기준도 sort와 다르다. 여기선 compare(a, b)로 저 조건이 쓰인다.
그래서 a>b에 대해 true가 나오면 a의 우선순위가 더 낮다 라는 뜻이므로 b(더 작은수)가 우선순위가 높아 top에 위치하게 된다. 만약 sort처럼 a<b로 써주면 true가 나온다면 a가 우선순위가 더 낮으므로 더 큰 수인 b가 top에 오게된다. 이부분 이해하는데 좀 걸렸다.
그리고 우선순위 큐를 선언하는데 두 번째 인자로 vector는 큐가 내부적으로 어떤 자료구조를 이용할지에 대한 인자이다. 즉 vector를 통해 자료구조를 처리한다는 뜻이다. 보통 vector를 사용한다고 한다.

0개의 댓글