본문 바로가기
코딩테스트 준비/백준

[백준] 2696번 - 중앙값 구하기 [Java]

by mwzz6 2025. 2. 12.

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

 

[백준] 2696번 - 중앙값 구하기 [Java]
[백준] 2696번 - 중앙값 구하기 [Java]


1.  아이디어

 

중앙값보다 작은 수들을 모은 우선순위 큐와 중앙값보다 큰 수들을 모은 우선순위 큐를 활용하면 해결할 수 있다.


2. 문제풀이

 

중앙값보다 작은 수들을 모은 우선순위 큐는 내림차순 정렬, 중앙값보다 큰 수들을 모은 우선순위 큐는 오름차순 정렬을 해서 두 우선순위 큐의 peek 값이 중앙값 바로 전후가 되도록 했다. 이후 두 우선순위 큐의 크기를 동일하게 유지만 하면 간단하게 중앙값을 구할 수 있다.


3. 코드

 

import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        StringBuilder sb = new StringBuilder();
        StringTokenizer st;

        int T = Integer.parseInt(br.readLine());
        for (int tc = 1; tc <= T; tc++) {
            int N = Integer.parseInt(br.readLine());
            sb.append((N + 1) / 2).append("\n");

            StringBuilder input = new StringBuilder();
            for (int i = 0; i <= N / 10; i++) {
                input.append(br.readLine()).append("\n");
            }

            // 작은 절반
            PriorityQueue<Integer> pq = new PriorityQueue<>(Collections.reverseOrder());
            // 큰 절반
            PriorityQueue<Integer> pq2 = new PriorityQueue<>();

            st = new StringTokenizer(input.toString());
            for (int i = 1; i <= N; i++) {
                int num = Integer.parseInt(st.nextToken());

                if (i % 2 == 1) {
                    if (!pq2.isEmpty() && num <= pq2.peek()) {
                        pq.add(num);
                    } else {
                        pq2.add(num);
                        pq.add(pq2.remove());
                    }
                } else {
                    if (!pq.isEmpty() && num >= pq.peek()) {
                        pq2.add(num);
                    } else {
                        pq.add(num);
                        pq2.add(pq.remove());
                    }
                }

                if (i % 2 == 1) sb.append(pq.peek()).append(" ");
                if (i % 20 == 0) sb.append("\n");
            }

            sb.append("\n");
        }

        bw.write(sb.toString());
        bw.flush();
    }
}

4. 후기