• 백준 7662번 이중 우선순위 큐 :: 마이구미
    알고리즘 풀이/스택, 큐 2017. 9. 22. 11:21
    반응형

    이 글은 백준 알고리즘 문제 7662번 "이중 우선순위 큐" 를 풀이한다.

    문제명과 같이 우선순위 큐를 이용해서 문제를 해결할 수 있다.

    본인은 풀고나서도 문제가 무엇을 원하는 것인지 잘 모르는 문제이기도하다.

    7662번 - https://www.acmicpc.net/problem/7662


    이중 우선순위 큐(dual priority queue)는 전형적인 우선순위 큐처럼 데이터를 삽입, 삭제할 수 있는 자료 구조이다. 전형적인 큐와의 차이점은 데이터를 삭제할 때 연산(operation) 명령에 따라 우선순위가 가장 높은 데이터 또는 가장 낮은 데이터 중 하나를 삭제하는 점이다. 이중 우선순위 큐를 위해선 두 가지 연산이 사용되는데, 하나는 데이터를 삽입하는 연산이고 다른 하나는 데이터를 삭제하는 연산이다. 데이터를 삭제하는 연산은 또 두 가지로 구분되는데 하나는 우선순위가 가장 높은 것을 삭제하기 위한 것이고 다른 하나는 우선순위가 가장 낮은 것을 삭제하기 위한 것이다. 

    정수만 저장하는 이중 우선순위 큐 Q가 있다고 가정하자. Q에 저장된 각 정수의 값 자체를 우선순위라고 간주하자. 

    Q에 적용될 일련의 연산이 주어질 때 이를 처리한 후 최종적으로 Q에 저장된 데이터 중 최대값과 최솟값을 출력하는 프로그램을 작성하라.


    우선 Java에서는 다음과 같이 우선순위 큐를 제공하고 있다.

    그리고 우선순위 큐는 내부적으로 Heap으로 구현되어있다.

    import java.util.PriorityQueue; PriorityQueue<> queue = new PriorityQueue<>();


    문제를 해결하기 위해 최솟값에 대한 큐와 최대값에 대한 2개의 큐를 이용한다.

    그 이유는 삭제하는 연산이 O(1)로 줄일 수 있게 된다.


    삽입할 때는 2개의 큐에 모두 삽입한다.

    삭제할 경우에는 삭제할 수 있는지 판단한 후 삭제를 한다.

    그 판단은 visited와 같은 배열을 통해서 할 수 있다.

    그 후, 다음 처리를 위해 2개의 큐의 동기화 작업을 한다.


    이와 같은 흐름으로 더욱 효율적으로 구현할 수 있는 방법은 TreeMap을 통해 할 수 있다.


    Github - https://github.com/hotehrud/acmicpc


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    private void solve() {
        int t = sc.nextInt();
        StringBuilder sb = new StringBuilder();
     
        while (t-- > 0) {
            int k = sc.nextInt();
            PriorityQueue<Pair> maxHeap = new PriorityQueue<>(new ComparatorDescending());
            PriorityQueue<Pair> minHeap = new PriorityQueue<>(new ComparatorAscending());
            boolean[] visited = new boolean[k];
     
            for (int i = 0; i < k; i++) {
                String[] input = sc.readLine().split(" ");
                String op = input[0];
                long n = Long.parseLong(input[1]);
     
                if (op.equals("I")) {
                    Pair p = new Pair(i, n);
                    minHeap.add(p);
                    maxHeap.add(p);
                } else {
                    if (n == 1) {
                        if (!maxHeap.isEmpty()) {
                            Pair p = maxHeap.peek();
                            if (!visited[p.idx]) {
                                maxHeap.poll();
                                visited[p.idx] = true;
                            }
                        }
                    } else {
                        if (!minHeap.isEmpty()) {
                            Pair p = minHeap.peek();
                            if (!visited[p.idx]) {
                                minHeap.poll();
                                visited[p.idx] = true;
                            }
     
                        }
                    }
                }
     
                while(!minHeap.isEmpty()) {
                    if (!visited[minHeap.peek().idx]) {
                        break;
                    } else {
                        minHeap.poll();
                    }
                }
     
                while(!maxHeap.isEmpty()) {
                    if (!visited[maxHeap.peek().idx]) {
                        break;
                    } else {
                        maxHeap.poll();
                    }
                }
            }
            if (maxHeap.isEmpty() || minHeap.isEmpty()) {
                sb.append("EMPTY\n");
            } else {
                sb.append(maxHeap.peek().value + " " + minHeap.peek().value + "\n");
            }
     
        }
        System.out.println(sb.toString());
    }
     
    class Pair {
        int idx;
        long value;
     
        Pair(int idx, long value) {
            this.idx = idx;
            this.value = value;
        }
    }
     
    class ComparatorDescending implements Comparator<Pair> {
        @Override
            public int compare(Pair p1, Pair p2) {
            // TODO Auto-generated method stub
            if (p1.value < p2.value) {
                return 1;
            } else {
                return -1;
            }
        }
    }
     
    class ComparatorAscending implements Comparator<Pair> {
        @Override
            public int compare(Pair p1, Pair p2) {
            // TODO Auto-generated method stub
            if (p1.value < p2.value) {
                return -1;
            } else {
                return 1;
            }
        }
    }
    cs


    반응형

    댓글 0

Designed by Tistory.