minghxx.blog
  • [백준 / 자바] 11286번 절댓값 힙 - 우선순위 큐
    2023년 12월 19일 22시 43분 10초에 업로드 된 글입니다.
    작성자: 민발자
    728x90

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

     

    11286번: 절댓값 힙

    첫째 줄에 연산의 개수 N(1≤N≤100,000)이 주어진다. 다음 N개의 줄에는 연산에 대한 정보를 나타내는 정수 x가 주어진다. 만약 x가 0이 아니라면 배열에 x라는 값을 넣는(추가하는) 연산이고, x가 0

    www.acmicpc.net

     

    문제

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

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

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

     

    입력

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

    18 // 연산개수 N
    1
    -1
    0
    0
    0
    1
    1
    -1
    -1
    2
    -2
    0
    0
    0
    0
    0
    0
    0

     

    출력

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

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

     

    풀이

     

    n의 최대 범위가 100,000이므로 O(NlogN) 시간 복잡도 알고리즘 적용

    데이터가 새로 삽입될 때마다 정렬이 필요하므로 우선순위 큐로 구현

    절댓값 정렬이 필요하므로 우선순위 큐의 정렬 기준을 직접 정의해야 함

     

    # x == 0

    큐가 비어있을 때 0 출력

    비어있지 않으면 절댓값이 최소인 값을 출력

    절대값이 같다면 음수를 우선 출력

     

    # x != 0

    큐에 넣어줌

    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    int n = Integer.parseInt(br.readLine()); // 연산 개수
    
    PriorityQueue<Integer> q = new PriorityQueue<>((o1, o2) -> {
        // 우선 순위 정렬기준 정의
        int firstAbs = Math.abs(o1);
        int secondAbs = Math.abs(o2);
    
        // 절대값이 같은 경우 음수 우선
        if(firstAbs == secondAbs) {
            return o1 > o2 ? 1 : -1;
        }
    
        // 절대값이 최소인 값 우선
        return firstAbs - secondAbs;
    });
    
    
    for(int i = 0; i < n; i++){
        int num = Integer.parseInt(br.readLine());
    
        if(num == 0){
            if(q.isEmpty()) { // 비어있으면 0 출력
                System.out.println("0");
            } else { // 우선순위 큐로 정렬했기 때문에 절댓값 최소, 같을 경우 음수를 우선으로 꺼냄
                System.out.println(q.poll());
            }
        } else { // 0이 아니면 q에 넣어줌
            q.add(num);
        }
    }

    우선순위 큐 처음 써봐서 어려웠다🤯

     

     

     

     

     

     

     

    728x90
    댓글