Algorithm/문제풀이

[분할 정복] 숫자 카드

lee308812 2019. 11. 30. 15:38

예제 입력 1

5

6 3 2 10 -10

8

10 9 -5 2 3 4 5 -10

예제 출력 1

1 0 0 1 1 0 0 1

 

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

 

10815번: 숫자 카드

첫째 줄에 상근이가 가지고 있는 숫자 카드의 개수 N(1 ≤ N ≤ 500,000)이가 주어진다. 둘째 줄에는 숫자 카드에 적혀있는 정수가 주어진다. 숫자 카드에 적혀있는 수는 -10,000,000보다 크거나 같고, 10,000,000보다 작거나 같다. 두 숫자 카드에 같은 수가 적혀있는 경우는 없다. 셋째 줄에는 M(1 ≤ M ≤ 500,000)이 주어진다. 넷째 줄에는 상근이가 가지고 있는 숫자 카드인지 아닌지를 구해야 할 M개의 정수가 주어지며, 이

www.acmicpc.net

#include <stdio.h>

constexpr int MAX_COUNT = 500000;

int N, M;
int num[MAX_COUNT];
int tempNum[MAX_COUNT];

void mergeSort(int data[], int start, int end)
{
	if (start >= end) return;
	int mid = (start + end) / 2;

	mergeSort(data, start, mid);
	mergeSort(data, mid + 1, end);

	int i = start;
	int j = mid + 1;
	int k = 0;

	while (i <= mid && j <= end)
	{
		if (data[i] <= data[j])
		{
			tempNum[k++] = data[i];
			i++;
		}
		else
		{
			tempNum[k++] = data[j];
			j++;
		}
	}

	while (i <= mid)
	{
		tempNum[k++] = data[i];
		i++;
	}

	while (j <= end)
	{
		tempNum[k++] = data[j];
		j++;
	}

	for (int i = start; i <= end; i++)
		data[i] = tempNum[i - start];
}

int main(void)
{
	scanf("%d", &N);

	for (register int i = 0; i < N; i++)
	{
		scanf("%d", &num[i]);
	}

	mergeSort(num, 0, N - 1);

	scanf("%d", &M);

	for (register int i = 0; i < M; i++)
	{
		int input;
		scanf("%d", &input);

		int start = 0;
		int end = N - 1;

		bool ok = false;

		while (start <= end)
		{
			int mid = (start + end) / 2;

			if (num[mid] == input)
			{
				ok = true;
				break;
			}

			if (input < num[mid]) end = mid - 1;
			else if (input > num[mid]) start = mid + 1;
		}

		if (ok) printf("1 ");
		else printf("0 ");
	}

	return 0;
}