알고리즘/[PRO] 삼성 SW 역량 테스트 B형

최대 힙, 절댓값 힙 - B형 Reference 코드 (우선순위 큐)

피로물든딸기 2021. 6. 5. 20:51
반응형

삼성 B형 전체 링크

 

B형 reference 코드의 우선순위 큐최소 힙만 주어져있다.

코드 변경을 최소화해서 최대 힙절댓값 힙을 풀어보자.


reference 코드에서 우선순위를 비교하는 곳을 수정하면 된다.

 

1) heapPush의

    while (current > 0 && heap[current] < heap[(current - 1) / 2])

 

2) heapPop의 

    child =
        heap[current * 2 + 1] < heap[current * 2 + 2] ? current * 2 + 1 : current * 2 + 2;

 

3) heapPop의

    if (heap[current] < heap[child])
    {
        break;
    }


최대 힙이라면 < 를 모두 >로 바꾸면 된다.

절댓값 힙의 경우 isMin 함수를 만들어서 우선순위를 판별하였다.

따라서 A < B 부분을 isMin(A, B)로 변경하면 된다.

 

최대 힙 코드는 아래와 같다.

#include <stdio.h>

#define MAX_SIZE (100100)

int N;
int heap[MAX_SIZE];
int heapSize;

int heapPush(int* heap, int& heapSize, int value)
{
	heap[heapSize] = value;

	int current = heapSize;
	while (current > 0 && heap[current] > heap[(current - 1) / 2]) /* 우선순위 변경 */
	{
		int temp = heap[(current - 1) / 2];
		heap[(current - 1) / 2] = heap[current];
		heap[current] = temp;
		current = (current - 1) / 2;
	}

	heapSize = heapSize + 1;

	return 1;
}

int heapPop(int* heap, int& heapSize, int *value)
{
	*value = heap[0];
	heapSize = heapSize - 1;

	heap[0] = heap[heapSize];

	int current = 0;
	while (current * 2 + 1 < heapSize)
	{
		int child;
		if (current * 2 + 2 == heapSize)
		{
			child = current * 2 + 1;
		}
		else
		{
			child = /* 우선순위 변경 */
				heap[current * 2 + 1] > heap[current * 2 + 2] ? current * 2 + 1 : current * 2 + 2;
		}

		if (heap[current] > heap[child]) /* 우선순위 변경 */
		{
			break;
		}

		int temp = heap[current];
		heap[current] = heap[child];
		heap[child] = temp;

		current = child;
	}
	return 1;
}

int main(void)
{
	scanf("%d", &N);
	for (int i = 0; i < N;i++)
	{
		int x;

		scanf("%d", &x);
		if (x) heapPush(heap, heapSize, x);
		else
		{
			if (heapSize)
			{
				int value;

				heapPop(heap, heapSize, &value);

				printf("%d\n", value);
			}
			else printf("0\n");
		}
	}

	return 0;
}

 

절댓값 힙 코드는 아래와 같다.

#include <stdio.h>

#define MAX_SIZE (100100)

int N;
int heap[MAX_SIZE];
int heapSize;

int abs(int x)
{
	return (x > 0) ? x : -x;
}

int isMin(int a, int b)
{
	if (abs(a) < abs(b)) return 1; /* 절댓값 중 작으면 우선순위가 크다 */
	if (abs(a) == abs(b) && a < b) return 1; /* 같은 절댓값이면 음수가 우선순위가 크다 */

	return 0;
}

int heapPush(int* heap, int& heapSize, int value)
{
	heap[heapSize] = value;

	int current = heapSize;
	while (current > 0 && isMin(heap[current], heap[(current - 1) / 2])) /* 우선순위 변경 */
	{
		int temp = heap[(current - 1) / 2];
		heap[(current - 1) / 2] = heap[current];
		heap[current] = temp;
		current = (current - 1) / 2;
	}

	heapSize = heapSize + 1;

	return 1;
}

int heapPop(int* heap, int& heapSize, int *value)
{
	*value = heap[0];
	heapSize = heapSize - 1;

	heap[0] = heap[heapSize];

	int current = 0;
	while (current * 2 + 1 < heapSize)
	{
		int child;
		if (current * 2 + 2 == heapSize)
		{
			child = current * 2 + 1;
		}
		else
		{
			child = /* 우선순위 변경 */
			 isMin(heap[current * 2 + 1], heap[current * 2 + 2]) ? current * 2 + 1 : current * 2 + 2;
		}

		if (isMin(heap[current], heap[child])) /* 우선순위 변경 */
		{
			break;
		}

		int temp = heap[current];
		heap[current] = heap[child];
		heap[child] = temp;

		current = child;
	}
	return 1;
}

int main(void)
{
	scanf("%d", &N);
	for (int i = 0; i < N;i++)
	{
		int x;

		scanf("%d", &x);
		if (x) heapPush(heap, heapSize, x);
		else
		{
			if (heapSize)
			{
				int value;

				heapPop(heap, heapSize, &value);

				printf("%d\n", value);
			}
			else printf("0\n");
		}
	}

	return 0;
}

실제 시험에서는 register도 추가해주자.

반응형