2024. 8. 22. 11:25ㆍETC/Algorithm
[유형]
자료구조
[문제링크]
https://www.acmicpc.net/problem/2696
[요약]
각 테스트 케이스에 대해 첫째 줄에 출력하는 중앙값의 개수를 출력하고, 둘째 줄에는 홀수 번째 수를 읽을 때 마다 구한 중앙값을 차례대로 공백으로 구분하여 출력한다. 이때, 한 줄에 10개씩 출력해야 한다.
[문제풀이]
먼저, 특정 N번째 원소까지의 중앙 값을 AkAk라고 가정한다면, 우리는 다음과 같이 이분화를 할 수 있게 된다.
A1 ... An = {Ak 보다 작은 원소들의 집합 } + { Ak 보다 크거나 같은 원소들의 집합 }
이 때, n이 홀수 일 때 유일한(unique) 중앙값이 하나가 정의가 되고 이 때 이것을 출력하고자 한다.
{ Ak 보다 작은 원소들의 집합 } 과 { Ak 보다 크거나 같은 원소들의 집합 } 은 최대 1이 차이나고, 항상 { Ak 보다 작은 원소들의 집합 }은 { Ak 보다 크거나 같은 원소들의 집합 } 보다 크거나 같다. 이렇게되면 { Ak 보다 작은 원소들의 집합 }의 루트 노드가 항상 중앙값임이 보장된다.
{ Ak 보다 작은 원소들의 집합 } 의 모든 원소들은 { Ak 보다 크거나 같은 원소들의 집합 } 의 모든 원소들 보다 작다.즉, { Ak 보다 작은 원소들의 집합 }의 최댓값이 { Ak 보다 크거나 같은 원소들의 집합 }의 최솟값 보다 작아야 한다는 것을 의미한다.
{ 보다 작은 원소들의 집합 }은 최댓값을 빠르게 구하기 위해 Max heap으로 구현을 하고
{ 보다 크거나 같은 원소들의 집합 }은 최솟값을 빠르게 구하기 위해 Min heap으로 구현을 한다.
1. 중앙값을 기준으로, 중앙값보다 작거나 같으면 max_heap에, 중앙값보다 크면 min_heap에 추가한다.
2. max_heap의 길이가, min_heap의 길이보다 2이상 길다면, max_heap의 루트 노드 값을 min_heap으로 이동.
3. max_heap의 길이보다 min_heap의 길이가 더 길다면, 길이가 같아질 때까지 min_heap의 루트 노트 값을 max_heap으로 이동.
4. i가 짝수일때, max_heap의 루트 노드 값을 medians에 append.
import sys
def input():
return sys.stdin.readline().rstrip()
import heapq
for _ in range(int(input())):
M = int(input())
num_list = list()
for i in range((M-1) // 10 + 1) :
num_list += list(map(int, input().split()))
min_heap = []
max_heap = [-num_list[0]]
medians = [num_list[0]]
for i in range(1,M):
if -max_heap[0] < num_list[i]:
heapq.heappush(min_heap, num_list[i])
else:
heapq.heappush(max_heap, -num_list[i])
while len(max_heap) -len(min_heap) > 1:
heapq.heappush(min_heap, -heapq.heappop(max_heap))
while len(max_heap) -len(min_heap) < 0:
heapq.heappush(max_heap, -heapq.heappop(min_heap))
if not i%2 :
medians.append(-max_heap[0])
print(len(medians))
for i in range(0, len(medians), 10):
print(*medians[i:min(i + 10, len(medians))])
참고 https://kangminjun.tistory.com/entry/BOJ-2696번-중앙값-구하기 [알고리즘 문제풀이:티스토리]
'ETC > Algorithm' 카테고리의 다른 글
백준,퇴사,14501 (0) | 2024.08.23 |
---|---|
백준, 영화감독 숌,1436 (0) | 2024.08.23 |
프로그래머스, 더 맵게 (0) | 2024.08.22 |
백준, N번째 큰 수 ,2075 (0) | 2024.08.22 |
백준, 최소 힙, 1927 (0) | 2024.08.22 |