7662번: 이중 우선순위 큐
입력 데이터는 표준입력을 사용한다. 입력은 T개의 테스트 데이터로 구성된다. 입력의 첫 번째 줄에는 입력 데이터의 수를 나타내는 정수 T가 주어진다. 각 테스트 데이터의 첫째 줄에는 Q에 적
www.acmicpc.net
💡 최대 힙과 최소 힙을 동시에 사용해서 푸는 문제입니다.
양쪽 힙에 동시에 데이터를 입력하되, 총 입력되었던 원소들을 기억하여 만약 이미 제거된 원소를 만난다면 추가로 제거 작업을 하는 방향으로 풀어야합니다.
문제 코드
package backjoon;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class boj7662 {
public void solution() throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
int testCases = Integer.parseInt(reader.readLine());
StringBuilder outBuilder = new StringBuilder();
for (int i = 0; i < testCases; i++) {
int commandCount = Integer.parseInt(reader.readLine());
// Collections.reverseOrder로 최대 힙
PriorityQueue<Integer> maxQueue
= new PriorityQueue<>(Collections.reverseOrder());
PriorityQueue<Integer> minQueue
= new PriorityQueue<>();
// Map 만들기
// Key: 입력 데이터, Value: 입력 데이터의 출현 횟수
Map<Integer, Integer> tracker = new HashMap<>();
int size = 0;
for (int j = 0; j < commandCount; j++) {
// I 숫자: 숫자를 삽입
// D 1: 최대 원소 제거
// D -1: 최소 원소 제거
StringTokenizer commandToken = new StringTokenizer(reader.readLine());
String command = commandToken.nextToken();
int number = Integer.parseInt(commandToken.nextToken());
if (command.equals("I")) {
// 두 우선순위 큐에 삽입
minQueue.offer(number);
maxQueue.offer(number);
tracker.put(number, tracker.getOrDefault(number, 0) + 1);
size++;
}
else if (number == 1 && size > 0){
// tracker에 키가 존재하는 원소가 나올때까지 queue에서 poll 한다.
// tracker에 키가 없다는 것은 입력된적 잇지만 다른 큐에 의해서 이미 빠져나갔다는 뜻
while (!tracker.containsKey(maxQueue.peek())) {
maxQueue.poll();
}
// 실제로 꺼낸 원소
int polled = maxQueue.poll();
// tracker 갱신
tracker.put(polled, tracker.get(polled) - 1);
if (tracker.get(polled) == 0) tracker.remove(polled);
size--;
}
else if (number == -1 && size > 0) {
while (!tracker.containsKey(minQueue.peek())) {
minQueue.poll();
}
int polled = minQueue.poll();
tracker.put(polled, tracker.get(polled) - 1);
if (tracker.get(polled) == 0) tracker.remove(polled);
size--;
}
}
if (size == 0) {
outBuilder.append("EMPTY\n");
} else {
while (!tracker.containsKey(maxQueue.peek())) {
maxQueue.poll();
}
while (!tracker.containsKey(minQueue.peek())) {
minQueue.poll();
}
outBuilder.append(maxQueue.poll())
.append(" ")
.append(minQueue.poll())
.append("\n");
}
}
System.out.println(outBuilder);
}
public static void main(String[] args) throws IOException {
new boj7662().solution();
}
}
출력 결과
입력
2
7
I 16
I -5643
D -1
D 1
D 1
I 123
D -1
9
I -45
I 653
D 1
I -642
I 45
I 97
D 1
D -1
I 333
출력
EMPTY
333 -45
'Algorithm' 카테고리의 다른 글
백준 2738 행렬 덧셈 (0) | 2023.07.16 |
---|---|
백준 11000 강의실 배정 (0) | 2023.07.14 |
백준 15903 카드 합체 놀이 (0) | 2023.07.13 |
백준 2447 별찍기10 (0) | 2023.07.12 |
백준 17829 222-풀링 (0) | 2023.07.12 |