기본 콘텐츠로 건너뛰기

백준알고리즘 1927번, 최소 힙 풀이

자연수 x를 입력받아 최소 힙에 입력하고 출력하는 문제입니다.
힙을 구현할때 push같은 경우에는 빈 정점에 넣어주기만해서 금방 잤는데
pop같은 경우에는 마지막 정점을 루트로 옮기고 루트와 자식노드간에 비교를 한번만 해서 계속 답이 틀렸었네요. 위치를 옮기고 나면 옮긴 위치에서 또 비교를 계속 해줘야됩니다. DFS나 BFS로 구현하면되는데, 저는 큐를 활용해 BFS로 구현했습니다

--------------------------------------------------------------------------------------------

#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <functional>
#include <utility>

using namespace std;

class Heap_min {
private:
unsigned int vertex[100000];
int empty_vertex;
int size;
queue<int> q;

public:

Heap_min() {
memset(vertex, 0xff, sizeof vertex);
empty_vertex = 0;
size = 0;
}
void push(unsigned int x) {
int parent,curr,temp;
size++;
vertex[empty_vertex] = x;
curr = empty_vertex;
parent = (curr - 1) / 2;
empty_vertex++;
while (vertex[parent] > vertex[curr]) {
temp = vertex[parent];
vertex[parent] = vertex[curr];
vertex[curr] = temp;
curr = parent;
parent = (curr - 1) / 2;
}

}
unsigned int pop() {
int lchild, rchild, parent, temp;
unsigned ret;
if (size == 0)
return 0;
size--;
ret = vertex[0];
vertex[0] = vertex[--empty_vertex];
vertex[empty_vertex] = 0xffffffff;
parent = 0;
q.push(parent);
while(!q.empty()){
if (q.front() > 49999) {
q.pop();
continue;
}
parent = q.front();
lchild = parent * 2 + 1;
rchild = parent * 2 + 2;
q.pop();

if(vertex[parent] > vertex[lchild]){
temp = vertex[parent];
vertex[parent] = vertex[lchild];
vertex[lchild] = temp;
q.push(lchild);
}

if (vertex[parent] > vertex[rchild]) {
temp = vertex[parent];
vertex[parent] = vertex[rchild];
vertex[rchild] = temp;
q.push(rchild);
}
}

return ret;
}

};

int main(void) {
Heap_min hm;
int N;
unsigned int x;

#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif

scanf("%d", &N);
for (int i = 0; i < N; i++) {
scanf("%d", &x);
if (x == 0) {
printf("%d\n", hm.pop());
}
else {
hm.push(x);
}

}
#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
#endif

return 0;

}

댓글

이 블로그의 인기 게시물

좌표압축

알 고리즘을 풀다 보면 좌표압축이라는 테크닉이 필요합니다. 저는 좌표압축을  "순위가 중요한 알고리즘에서, 입력값의 갯수보다 입력값의 범위가 클 때 사용하는 방법",  이라고 생각하고 있습니다. 1차원의 좌표로 예를 들어보겠습니다. n개의 x값 을 입력 받아, 입력 중 두개의  x1,x2를 선택하여 사이에 존재하는 점의 개수를 구하는 작업이 있다고 가정합시다. x의 범위는 int형의 범위인 -2^31 ~ 2^31-1 이고 중복은 없습니다. n은 5000 이하입니다. 입력은 n : 7, -2^31, -10000, 0 , -2000, 3, 6, 30000 , x1 = -10000, x2 = 30000 대략적으로 보면 그림과 같이 나타나게 됩니다. x1,x2 사이의 값을 구하게 되면 4개의 값이 나오게 됩니다. 이 경우 위의 값들을 아래와 같이 순위를 유지하면서 바꿔주어도 문제를 풀 수가있습니다. 이렇게   바꿔서 풀 수 있는 이유는 값보다 값의 순위가 중요하기 때문 입 니다. 압축좌표가  필요한 예 로, 카카오 코드 페스티벌 5번 캠핑 문제가 될 수 있습니다. 이 경우 좌표  x,y의 범위는 0 ~ 2^31-1  이지만, 입력받는  좌표의 개수는 최대 5000개  입니다. 만약 입력의 좌표를 그대로 반영하여 문제를 푼다고 하면 배열의 크기가 2^31-1 개가 되어야 합니다. 게다가 2차원으로.. 못풉니다. 탐색하다가 시간다 끝날꺼에요. 하지만 입력이 최대의 개수가 최대 5000이라고 했으니 좌표압축을 이용해 입력받은 좌표를 0~5000 으로 매치시키고 풀게되는 것 입니다.