https://www.acmicpc.net/problem/1927
1927번: 최소 힙
첫째 줄에 연산의 개수 N(1 ≤ N ≤ 100,000)이 주어진다. 다음 N개의 줄에는 연산에 대한 정보를 나타내는 정수 x가 주어진다. 만약 x가 자연수라면 배열에 x라는 값을 넣는(추가하는) 연산이고, x가 0
www.acmicpc.net
문제
- 배열에 자연수 x를 넣는다.
- 배열에서 가장 작은 값을 출력하고, 그 값을 배열에서 제거한다.
기능을 수행하는 최소 힙을 구현하면 된다.
N개의 숫자 x가 들어온다. x가 0이면 최솟값을 출력하고 그 값을 배열에서 제거한다. 그렇지 않으면 x를 큐에 삽입한다.
풀이
템플릿은 https://github.com/encrypted-def/basic-algo-lecture/blob/master/0x17/heap_test.cpp 이걸 썼다.
push 함수
배열 제일 끝 (sz)에 넣고, 부모 (cur/2)와 비교하여 자리를 바꾸면서 root까지 올라간다.
top 함수
큐가 비어있지 않다면 heap[1]을 출력한다.
pop 함수
heap[1] <-> heap[sz]를 바꾸고, root부터 cur, cur*2, cur*2+1끼리 비교해서 최솟값 <-> cur을 바꿔 내려간다.
무수한 시간 초과가 났던 이유는 ...
ios::sync_with_stdio(0);
cin.tie(0);
이걸 빼먹음
위 링크의 스켈레톤 코드를 복붙하다가 저 코드를 빼먹었다
전체 코드
/*boj s2 1927 최소 힙*/
#include <algorithm>
#include <iostream>
using namespace std;
int heap[100005];
int sz = 0; // heap에 들어있는 원소의 수
void push(int x) {
heap[++sz] = x;
int cur = sz;
while (cur != 1) {
if (heap[cur / 2] > heap[cur]) {
swap(heap[cur / 2], heap[cur]);
cur = cur / 2;
} else {
break;
}
}
}
int top() {
if (sz == 0) {
return 0;
} else
return heap[1];
}
void pop() {
if (sz == 0) {
return;
}
// 1. root <-> 맨 끝
heap[1] = heap[sz--];
// 2. root부터 최솟값과 바꾸면서 내려가기
int cur = 1;
while (2 * cur <= sz) {
// 2-1. cur, cur*2, cur*+1 중 최솟값 찾기
int mn = heap[cur];
if (cur * 2 <= sz) {
mn = min(mn, heap[cur * 2]);
}
if (cur * 2 + 1 <= sz) {
mn = min(mn, heap[cur * 2 + 1]);
}
if (mn == heap[cur])
break;
else if (mn == heap[cur * 2]) {
swap(heap[cur], heap[cur * 2]);
cur = cur * 2;
} else if (mn == heap[cur * 2 + 1]) {
swap(heap[cur], heap[cur * 2 + 1]);
cur = cur * 2 + 1;
}
}
}
int N;
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> N;
int x;
while (N--) {
cin >> x;
if (x == 0) {
cout << top() << "\n";
pop();
} else {
push(x);
}
}
}
'알고리즘' 카테고리의 다른 글
백준 g4 1715 카드 정렬하기 c++ (0) | 2024.03.14 |
---|---|
백준 s1 11286 절댓값 힙 c++ (0) | 2024.03.13 |
백준 g1 19700 수업 c++ (0) | 2024.03.12 |
백준 g2 21944 문제 추천 시스템 Version 2 c++ (0) | 2024.03.12 |
백준 g3 23326 홍익 투어리스트 c++ (0) | 2024.03.11 |