728x90

괄호 

시간 제한메모리 제한제출정답맞힌 사람정답 비율
1 초 128 MB 199349 93844 67449 45.933%

문제

괄호 문자열(Parenthesis String, PS)은 두 개의 괄호 기호인 ‘(’ 와 ‘)’ 만으로 구성되어 있는 문자열이다. 그 중에서 괄호의 모양이 바르게 구성된 문자열을 올바른 괄호 문자열(Valid PS, VPS)이라고 부른다. 한 쌍의 괄호 기호로 된 “( )” 문자열은 기본 VPS 이라고 부른다. 만일 x 가 VPS 라면 이것을 하나의 괄호에 넣은 새로운 문자열 “(x)”도 VPS 가 된다. 그리고 두 VPS x 와 y를 접합(concatenation)시킨 새로운 문자열 xy도 VPS 가 된다. 예를 들어 “(())()”와 “((()))” 는 VPS 이지만 “(()(”, “(())()))” , 그리고 “(()” 는 모두 VPS 가 아닌 문자열이다. 

여러분은 입력으로 주어진 괄호 문자열이 VPS 인지 아닌지를 판단해서 그 결과를 YES 와 NO 로 나타내어야 한다. 

입력

입력 데이터는 표준 입력을 사용한다. 입력은 T개의 테스트 데이터로 주어진다. 입력의 첫 번째 줄에는 입력 데이터의 수를 나타내는 정수 T가 주어진다. 각 테스트 데이터의 첫째 줄에는 괄호 문자열이 한 줄에 주어진다. 하나의 괄호 문자열의 길이는 2 이상 50 이하이다. 

출력

출력은 표준 출력을 사용한다. 만일 입력 괄호 문자열이 올바른 괄호 문자열(VPS)이면 “YES”, 아니면 “NO”를 한 줄에 하나씩 차례대로 출력해야 한다. 

예제 입력 1 복사

6
(())())
(((()())()
(()())((()))
((()()(()))(((())))()
()()()()(()()())()
(()((())()(

예제 출력 1 복사

NO
NO
YES
NO
YES
NO

예제 입력 2 복사

3
((
))
())(()

예제 출력 2 복사

NO
NO
NO

 

 

'{'를 +, '}' 를 -라 생각하고

하나의 변수를 0으로 설정한 후, 최종 결과가 0이면 된다.

하지만, } { 의 경우 vps 형태가 아니지만 위 조건을 만족하므로

이 경우를 잡기 위해, 위에서 설정한 변수가 음수가 되는 순간 vps가 아닌걸로 판단해야 한다. 

 

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

char is_vps(char* input, int size) {
	int check = 0;
	for (int i = 0; i < size; i++) {
		if(check>=0)
		{
			if (input[i] == '(')
				check++;
			else if (input[i] == ')')
				check--;
			else continue;
		}
		else
			return 0;
	}
	if (check == 0)
		return 1;
	else
		return 0;
}
int main() {
	int size = 0;
	scanf("%d", &size);

	char** p = (char**)malloc(sizeof(char*) * size);
	for (int i = 0; i < size; i++) {
		p[i] = (char*)malloc(sizeof(char) * 51); //문제에서 최대 길이가 50이므로, null값까지 생각하여 51
		scanf("%s", p[i]);
	}

	//check and print
	for (int i = 0; i < size; i++) {
		if (is_vps(p[i], 51))
			printf("YES\n");
		else
			printf("NO\n");
	}
	

	//free
	for (int i = 0; i < size; i++)
		free(p[i]);
	free(p);

	return 0;
}
728x90

'알고리즘 > 백준' 카테고리의 다른 글

[백준] 2292 벌집  (0) 2024.02.26
[백준] 10814 나이순 정렬  (0) 2024.02.25
[백준] 2798 블랙잭  (1) 2024.02.25
[백준] 1929 소수 구하기  (0) 2024.02.22
[백준] 1920 수 찾기  (0) 2024.02.19
728x90

블랙잭 

시간 제한메모리 제한제출정답맞힌 사람정답 비율
1 초 128 MB 171794 85684 65577 48.618%

문제

카지노에서 제일 인기 있는 게임 블랙잭의 규칙은 상당히 쉽다. 카드의 합이 21을 넘지 않는 한도 내에서, 카드의 합을 최대한 크게 만드는 게임이다. 블랙잭은 카지노마다 다양한 규정이 있다.

한국 최고의 블랙잭 고수 김정인은 새로운 블랙잭 규칙을 만들어 상근, 창영이와 게임하려고 한다.

김정인 버전의 블랙잭에서 각 카드에는 양의 정수가 쓰여 있다. 그 다음, 딜러는 N장의 카드를 모두 숫자가 보이도록 바닥에 놓는다. 그런 후에 딜러는 숫자 M을 크게 외친다.

이제 플레이어는 제한된 시간 안에 N장의 카드 중에서 3장의 카드를 골라야 한다. 블랙잭 변형 게임이기 때문에, 플레이어가 고른 카드의 합은 M을 넘지 않으면서 M과 최대한 가깝게 만들어야 한다.

N장의 카드에 써져 있는 숫자가 주어졌을 때, M을 넘지 않으면서 M에 최대한 가까운 카드 3장의 합을 구해 출력하시오.

입력

첫째 줄에 카드의 개수 N(3 ≤ N ≤ 100)과 M(10 ≤ M ≤ 300,000)이 주어진다. 둘째 줄에는 카드에 쓰여 있는 수가 주어지며, 이 값은 100,000을 넘지 않는 양의 정수이다.

합이 M을 넘지 않는 카드 3장을 찾을 수 있는 경우만 입력으로 주어진다.

출력

첫째 줄에 M을 넘지 않으면서 M에 최대한 가까운 카드 3장의 합을 출력한다.

예제 입력 1 복사

5 21
5 6 7 8 9

예제 출력 1 복사

21

예제 입력 2 복사

10 500
93 181 245 214 315 36 185 138 216 295

예제 출력 2 복사

497

 

 

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <math.h>
#include <stdlib.h>

//long factorial(int n) {
//	long temp = 1;
//	for (int i = 1; i <= n; i++)
//		temp *= i;
//	return temp;
//}
//
//long binomial_coefficient(int n, int k) {
//	if (k >= 0 && k <= n)
//		return factorial(n) / (factorial(k) * factorial(n - k));
//	return 0;
//}

void get_all_sum(int* input, long* output, int size, int boundary) {
	int i = 0, j = 1, k = 2;
	int index = 0;
	for (i = 0; i < j; i++) {
		for (j = i + 1; j < k ; j++) {
			for (k = j + 1; k < size; k++) {
				long temp = input[i] + input[j] + input[k];
				if (temp <= boundary)
					output[index++] = temp;
			}
		}
	}
	return;
}

int main() {
	int size = 0, boundary = 0;
	long long size_of_array_sum;
	scanf("%d %d", &size, &boundary);
	int* array = (int*)malloc(sizeof(int) * size);
	size_of_array_sum = (size * (size - 1) * (size - 2)) / 6;//binomial_coefficient(size, 3);

	long* sum_array = (long*)malloc(sizeof(long) * size_of_array_sum);
	int* diff_array = (int*)malloc(sizeof(int) * size_of_array_sum);

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

	// nC3으로 가능한 조합 합 모두 sum_array에 입력
	get_all_sum(array, sum_array, size, boundary);

	//boundary와 합 배열의 절대값 차이 계산
	for (int i = 0; i < size_of_array_sum; i++) {
		diff_array[i] = abs(boundary - sum_array[i]);
	}

	//계산한 절대값 차이 중 가장 작은 값의 인덱스 구하기
	int min = 300001; //문제에서 나올 수 있는 boundary 최대값 + 1
	int index_of_min = 0; //절대값 차가 가장 적은 sum_array의 index;
	for (int i = 0; i < size_of_array_sum; i++) {
		if (diff_array[i] < min) {
			min = diff_array[i];
			index_of_min = i;
		}
	}

	printf("%d", sum_array[index_of_min]);
	free(array);
	free(sum_array);
	free(diff_array);

}

 

가능한 모든 조합의 합을 저장하기 위한 size를 계산하기 위해서, 이항계수를 사용하려 시도했고, 이를 위해 factorial함수를 구현했지만, 수가 조금만 커저도 long long으로도 저장할 수 없어 다른 방법을 선택하였다. 

nCr에서 r값이 고정되어 있으므로, n! / {r!*(n-r)!} 을 계산하는 대신에 n(n-1)(n-2) / 6 을 사용하였다.

 

3중 for문을 이용해 모든 조합을 구하는 로직도, for문을 작성할때 중괄호 내 함수 동작 조건과 실행 후 연산을 신경써서 작성하면 쉽게 구현할 수 있다.

728x90

'알고리즘 > 백준' 카테고리의 다른 글

[백준] 10814 나이순 정렬  (0) 2024.02.25
[백준] 9012 괄호  (0) 2024.02.25
[백준] 1929 소수 구하기  (0) 2024.02.22
[백준] 1920 수 찾기  (0) 2024.02.19
[백준] 1676 팩토리얼 0의 개수  (0) 2024.02.17
728x90

카드2 성공

시간 제한메모리 제한제출정답맞힌 사람정답 비율
2 초 (추가 시간 없음) 128 MB 113816 59132 46098 50.951%

문제

 

N장의 카드가 있다. 각각의 카드는 차례로 1부터 N까지의 번호가 붙어 있으며, 1번 카드가 제일 위에, N번 카드가 제일 아래인 상태로 순서대로 카드가 놓여 있다.

이제 다음과 같은 동작을 카드가 한 장 남을 때까지 반복하게 된다. 우선, 제일 위에 있는 카드를 바닥에 버린다. 그 다음, 제일 위에 있는 카드를 제일 아래에 있는 카드 밑으로 옮긴다.

예를 들어 N=4인 경우를 생각해 보자. 카드는 제일 위에서부터 1234 의 순서로 놓여있다. 1을 버리면 234가 남는다. 여기서 2를 제일 아래로 옮기면 342가 된다. 3을 버리면 42가 되고, 4를 밑으로 옮기면 24가 된다. 마지막으로 2를 버리고 나면, 남는 카드는 4가 된다.

N이 주어졌을 때, 제일 마지막에 남게 되는 카드를 구하는 프로그램을 작성하시오.

입력

첫째 줄에 정수 N(1 ≤ N ≤ 500,000)이 주어진다.

출력

첫째 줄에 남게 되는 카드의 번호를 출력한다.

예제 입력 1 복사

6

예제 출력 1 복사

4

 

 

이 문제는 STL을 활용하여 간단하게 풀 수 있다.

문제에서 카드를 섞고 버리는 방식은 queue 자료구조 (FIFO)이므로, c++ 의  queue라이브러리를 활용하여 작성하였다.

#include <queue>
#include <iostream>
using namespace std;
int main() {
	queue<int> q;
	int num, temp;
	cin >> num;

	//initial
	for (int i = 1; i <= num; i++) {
		q.push(i);
	}

	//pop_push
	while (q.size() != 1) {
		temp = 0; //initialize

		q.pop();
		temp = q.front();
		q.pop();
		q.push(temp);

	}

	cout << q.front();
}

 

1부터 차례로 카드를 쌓으므로 for문을 활용하여 차례대로 push하고, 

while문에서 첫 카드를 버리고 (pop), 두번째 카드를 뽑아 가장 아래 위치로 넣는 작업 (temp에 front를 저장한 후, pop, push(temp)) 을 구현하였다.

 

728x90

'자료구조론 > 백준' 카테고리의 다른 글

[백준] 11866 요세푸스 문제 0  (0) 2024.02.25
[백준] 10866 덱  (0) 2024.02.25
[백준] 1966 프린터 큐  (1) 2024.02.24
[백준] 1874 스택 수열  (2) 2024.02.18
[백준] 10845번 큐  (2) 2023.12.25
728x90

프린터 큐 

시간 제한메모리 제한제출정답맞힌 사람정답 비율
2 초 128 MB 75441 43455 34243 58.540%

문제

여러분도 알다시피 여러분의 프린터 기기는 여러분이 인쇄하고자 하는 문서를 인쇄 명령을 받은 ‘순서대로’, 즉 먼저 요청된 것을 먼저 인쇄한다. 여러 개의 문서가 쌓인다면 Queue 자료구조에 쌓여서 FIFO - First In First Out - 에 따라 인쇄가 되게 된다. 하지만 상근이는 새로운 프린터기 내부 소프트웨어를 개발하였는데, 이 프린터기는 다음과 같은 조건에 따라 인쇄를 하게 된다.

  1. 현재 Queue의 가장 앞에 있는 문서의 ‘중요도’를 확인한다.
  2. 나머지 문서들 중 현재 문서보다 중요도가 높은 문서가 하나라도 있다면, 이 문서를 인쇄하지 않고 Queue의 가장 뒤에 재배치 한다. 그렇지 않다면 바로 인쇄를 한다.

예를 들어 Queue에 4개의 문서(A B C D)가 있고, 중요도가 2 1 4 3 라면 C를 인쇄하고, 다음으로 D를 인쇄하고 A, B를 인쇄하게 된다.

여러분이 할 일은, 현재 Queue에 있는 문서의 수와 중요도가 주어졌을 때, 어떤 한 문서가 몇 번째로 인쇄되는지 알아내는 것이다. 예를 들어 위의 예에서 C문서는 1번째로, A문서는 3번째로 인쇄되게 된다.

입력

첫 줄에 테스트케이스의 수가 주어진다. 각 테스트케이스는 두 줄로 이루어져 있다.

테스트케이스의 첫 번째 줄에는 문서의 개수 N(1 ≤ N ≤ 100)과, 몇 번째로 인쇄되었는지 궁금한 문서가 현재 Queue에서 몇 번째에 놓여 있는지를 나타내는 정수 M(0 ≤ M < N)이 주어진다. 이때 맨 왼쪽은 0번째라고 하자. 두 번째 줄에는 N개 문서의 중요도가 차례대로 주어진다. 중요도는 1 이상 9 이하의 정수이고, 중요도가 같은 문서가 여러 개 있을 수도 있다.

출력

각 테스트 케이스에 대해 문서가 몇 번째로 인쇄되는지 출력한다.

예제 입력 1 복사

3
1 0
5
4 2
1 2 3 4
6 0
1 1 9 1 1 1

예제 출력 1 복사

1
2
5

 

 

큐를 직접 구현하는것도 좋지만, 이번엔 stl문제인 만큼 오랜만에 c++ 라이브러리를 활용하여 풀어보았다.

 

#include <iostream>
#include <deque>
using namespace std;

struct PrintJob {
	int priority;
	bool check;
};

void printer_queue(int num_of_document, int index_of_searching){
	
	int most_prior = 0;
	int num_printed = 1;
	std::deque<PrintJob> q1;
	struct PrintJob temp = { 0,0 };

	//우선순위 배열 입력받기
	for (int i = 0; i < num_of_document; i++) {
 		std::cin >> temp.priority;

		if (i == index_of_searching) {
			temp.check = 1;
			q1.push_back(temp);
		}
		else {
			temp.check = 0;
			q1.push_back(temp);
		}
	}

	while (q1.size() != 0) {
		most_prior = 0; //초기화

		for (int i = 0; i < q1.size(); i++) { //가장 우선순위 탐색
			if (q1[i].priority > most_prior)
				most_prior = q1[i].priority;
		}

		while (q1[0].priority != most_prior) { //가장 앞의 문서가 가장 우선순위가 높은 문서일때까지
			if (q1[0].priority < most_prior) { //우선순위가 낮은 문서는 뒤로
				temp = q1[0];
				q1.pop_front();
				q1.push_back(temp);
			}
		}

		if (q1[0].check == 1) { //찾는 문서이면 출력 횟수를 출력한 후, 리턴
			cout << num_printed << endl;
			return;
		}
		else { //찾는 문서가 아닐 경우, pop하고 다시 탐색
			q1.pop_front();
			num_printed++;	
		}
		
	}
	

}


int main() {
	int num_of_testcase;
	int num_of_document;
	int index_of_searching;

	std::cin >> num_of_testcase;
	for (int i = 0; i < num_of_testcase; i++) {
		std::cin >> num_of_document; 
		std::cin >> index_of_searching; 
		printer_queue(num_of_document, index_of_searching);
	}
	return 0;
}
728x90

'자료구조론 > 백준' 카테고리의 다른 글

[백준] 11866 요세푸스 문제 0  (0) 2024.02.25
[백준] 10866 덱  (0) 2024.02.25
[백준] 2164 카드2  (1) 2024.02.24
[백준] 1874 스택 수열  (2) 2024.02.18
[백준] 10845번 큐  (2) 2023.12.25
728x90

분해합 

한국어   

 

시간 제한메모리 제한제출정답맞힌 사람정답 비율
2 초 192 MB 148795 68780 54079 45.415%

문제

어떤 자연수 N이 있을 때, 그 자연수 N의 분해합은 N과 N을 이루는 각 자리수의 합을 의미한다. 어떤 자연수 M의 분해합이 N인 경우, M을 N의 생성자라 한다. 예를 들어, 245의 분해합은 256(=245+2+4+5)이 된다. 따라서 245는 256의 생성자가 된다. 물론, 어떤 자연수의 경우에는 생성자가 없을 수도 있다. 반대로, 생성자가 여러 개인 자연수도 있을 수 있다.

자연수 N이 주어졌을 때, N의 가장 작은 생성자를 구해내는 프로그램을 작성하시오.

입력

첫째 줄에 자연수 N(1 ≤ N ≤ 1,000,000)이 주어진다.

출력

첫째 줄에 답을 출력한다. 생성자가 없는 경우에는 0을 출력한다.

예제 입력 1 복사

216

예제 출력 1 복사

198

 

입력이 1,000,000까지 가능하고, 사용자에게로부터 입력받은 수를 생성하는 수를 구해야 한다.

따라서, 어떤수를 입력에 넣고 그 수의 분해합을 구하는 프로그램을 작성하되, 여섯자리 수까지만 고려하면 된다.

 

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int calculate_num(int num) {
	int six, five, four, three, two, one;
	six = num / 100000;
	five = num / 10000 - six*10;
	four = num / 1000 - six * 100 - five*10;
	three = num / 100 - six * 1000 - five*100 - four*10;
	two = num / 10 - six*10000 - five*1000 - four*100 - three*10;
	one = num - six*100000 - five*10000 - four*1000 - three*100 - two*10;

	return num + six + five + four + three + two + one;
}

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

	for (int i = 1; i <= num; i++) {
		if (calculate_num(i) == num) {
			printf("%d", i);
			return 0;
		}
			
	}
	printf("0");
	return 0;
}
728x90

'C, C++ > 백준' 카테고리의 다른 글

[백준] 11650 좌표 정렬하기  (2) 2024.02.25
[백준] 10816 숫자 카드 2  (1) 2024.02.25
[백준] 1546 평균  (1) 2024.02.15
[백준] 1436 영화감독 숌  (1) 2024.02.10
[백준] 1259 팬린드롬수  (1) 2024.02.10
728x90

소수 찾기 

 
시간 제한메모리 제한제출정답맞힌 사람정답 비율
2 초 128 MB 198581 93911 75088 47.164%

문제

주어진 수 N개 중에서 소수가 몇 개인지 찾아서 출력하는 프로그램을 작성하시오.

입력

첫 줄에 수의 개수 N이 주어진다. N은 100이하이다. 다음으로 N개의 수가 주어지는데 수는 1,000 이하의 자연수이다.

출력

주어진 수들 중 소수의 개수를 출력한다.

예제 입력 1 복사

4
1 3 5 7

예제 출력 1 복사

3

 

https://2020270127.tistory.com/236

 

[백준] 1929 소수 구하기

소수 구하기 시간 제한메모리 제한제출정답맞힌 사람정답 비율 2 초 256 MB 269967 79590 55961 27.478% 문제 M이상 N이하의 소수를 모두 출력하는 프로그램을 작성하시오. 입력 첫째 줄에 자연수 M과 N이

2020270127.tistory.com

여기서 작성한 코드를 일부 수정하면 쉽게 풀 수 있다.

 

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

int arr[1000001]; //전역 변수 선언시 자동으로 0으로 초기화. 소수면 0, 아니면 1
int count;
void count_prime(int a, int b)
{
	//2,4,6,8 2(1,2,3,4,)  -> j (i) 
	//3,6,9,12 3(1,2,3,4,)
	arr[0] = 1;
	arr[1] = 1;
	
	for (int i = 2; i <= b; i++) {
		for (int j = 2 * i; j <= b; j += i) {
			if (arr[j] == 0) {
				arr[j] = 1; 
			}
		}
	}
	

	for (int i = a; i <= b; i++) {
		if (!arr[i])
			count++;//printf("%d\n", i);
	}
}

int main()
{
	int n;
	scanf("%d", &n);
	int* arr = (int*)malloc(sizeof(int) * n);
	for (int i = 0; i < n; i++) {
		scanf("%d", &arr[i]);
	}
	for (int i = 0; i < n; i++) {
		count_prime(arr[i], arr[i]);
	}
	printf("%d", count);
	

	return 0;
}
728x90
728x90

소수 구하기 

 
시간 제한메모리 제한제출정답맞힌 사람정답 비율
2 초 256 MB 269967 79590 55961 27.478%

문제

M이상 N이하의 소수를 모두 출력하는 프로그램을 작성하시오.

입력

첫째 줄에 자연수 M과 N이 빈 칸을 사이에 두고 주어진다. (1 ≤ M ≤ N ≤ 1,000,000) M이상 N이하의 소수가 하나 이상 있는 입력만 주어진다.

출력

한 줄에 하나씩, 증가하는 순서대로 소수를 출력한다.

예제 입력 1 복사

3 16

예제 출력 1 복사

3
5
7
11
13

 

 

위 문제는 모든 가능한 수로 나눠보면서, 나머지를 확인하는 방법보다, 에라토스테네스의 체를 활용하여 배수들을 제거해나가는 방식으로 풀어야 시간제한 안에 풀린다.

https://ko.wikipedia.org/wiki/%EC%97%90%EB%9D%BC%ED%86%A0%EC%8A%A4%ED%85%8C%EB%84%A4%EC%8A%A4%EC%9D%98_%EC%B2%B4

 

에라토스테네스의 체 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 에라토스테네스의 체 수학에서 에라토스테네스의 체는 소수를 찾는 빠르고 쉬운 방법이다. 고대 그리스 수학자 에라토스테네스가 발견하였다. 알고리즘[편집]

ko.wikipedia.org

 

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int arr[1000001]; //전역 변수 선언시 자동으로 0으로 초기화. 소수면 0, 아니면 1

void print_prime(int a, int b)
{
	
	//2,4,6,8 2(1,2,3,4,)  -> j (i) 
	//3,6,9,12 3(1,2,3,4,)
	arr[0] = 1;
	arr[1] = 1;
	
	for (int i = 2; i <= b; i++) {
		for (int j = 2 * i; j <= b; j += i) {
			if (arr[j] == 0) {
				arr[j] = 1; 
			}
		}
	}
	

	for (int i = a; i <= b; i++) {
		if (!arr[i])
			printf("%d\n", i);
	}
}

int main()
{
	int m, n;
	scanf("%d %d", &m, &n);

	print_prime(m, n);

	return 0;
}
728x90

'알고리즘 > 백준' 카테고리의 다른 글

[백준] 9012 괄호  (0) 2024.02.25
[백준] 2798 블랙잭  (1) 2024.02.25
[백준] 1920 수 찾기  (0) 2024.02.19
[백준] 1676 팩토리얼 0의 개수  (0) 2024.02.17
[백준] 1654 랜선 자르기  (0) 2024.02.16
728x90

수 찾기

 
시간 제한메모리 제한제출정답맞힌 사람정답 비율

 

1 초 128 MB 249191 76985 51061 29.991%

문제

N개의 정수 A[1], A[2], …, A[N]이 주어져 있을 때, 이 안에 X라는 정수가 존재하는지 알아내는 프로그램을 작성하시오.

입력

첫째 줄에 자연수 N(1 ≤ N ≤ 100,000)이 주어진다. 다음 줄에는 N개의 정수 A[1], A[2], …, A[N]이 주어진다. 다음 줄에는 M(1 ≤ M ≤ 100,000)이 주어진다. 다음 줄에는 M개의 수들이 주어지는데, 이 수들이 A안에 존재하는지 알아내면 된다. 모든 정수의 범위는 -231 보다 크거나 같고 231보다 작다.

출력

M개의 줄에 답을 출력한다. 존재하면 1을, 존재하지 않으면 0을 출력한다.

예제 입력 1 복사

5
4 1 5 2 3
5
1 3 7 9 5

예제 출력 1 복사

1
1
0
0
1

 

시간 제한이 1초인 문제이므로, A배열에서 수를 찾을때, 정렬 후 이진 탐색으로 찾아야 한다.

 

#define _CRT_SECURE_NO_WARNINGS	
#include <stdio.h>
#include <stdlib.h>

int previous_compare_int(const void* a, const void* b){
	return (*(int*)a-*(int*)b)
}

int compare_int(const void* a, const void* b) {
	int int_a = *(const int*)a;
	int int_b = *(const int*)b;

	if (int_a < int_b) return -1; 
	if (int_a > int_b) return 1;  
	return 0; 
}

//only if array1, array2 's size is same, and array1 is sorted
void check_and_print(int* array1, int* array2, int num_array1, int num_array2) {
	char flag = 0; //default is 0
	int left, right, middle, search_value;
	
	for (int i = 0; i < num_array2; i++) { //find array2's member in array1
		left = 0;
		right = num_array1 - 1;
		search_value = array2[i];

		//b-search
		while (left <= right) {
			middle = left + (right - left) / 2;
			if (array1[middle] > search_value) {
				right = middle - 1;
			}
			else if (array1[middle] < search_value) {
				left = middle + 1;
			}
			else if (array1[middle] == search_value){
				flag = 1;
				break;
			}
		}

		//here to print
		if (flag) {
			printf("1\n");
			flag = 0;
		}
		else {
			printf("0\n");
		}
	}
 }

int main() {
	int num_array1 = 0;
	int num_array2 = 0;
	int* array1 = NULL;
	int* array2 = NULL;


	scanf("%d", &num_array1);
	array1 = (int*)malloc(sizeof(int) * num_array1);
	for (int i = 0; i < num_array1; i++) {
		scanf("%d", &array1[i]);
	}

	scanf("%d", &num_array2);
	array2 = (int*)malloc(sizeof(int) * num_array2);
	for (int i = 0; i < num_array2; i++) {
		scanf("%d", &array2[i]);
	}
	
	qsort(array1, num_array1, sizeof(int), compare_int);
	

	check_and_print(array1, array2, num_array1, num_array2);
	
	free(array1);
	free(array2);

	return 0;
}

 

"previous_compare_int"는 초반에 작성한 함수로, 첫번째 인자가 큰 경우 양수, 같을경우 0, 두번째 인자가 클 경우 음수를 반환하게 설계하였지만, 입력의 최댓값이 2^31이므로 차를 구하는 과정에서 첫 인자가 2^31 - 1, 두번째 인자가 -1 이하긴 경우에 integer_overflow가 발생하므로 의도한대로 함수가 작동하지 않는다.

따라서, 대소 비교 후 +1, 0, -1을 반환하는 함수로 변경하였다.

728x90

'알고리즘 > 백준' 카테고리의 다른 글

[백준] 2798 블랙잭  (1) 2024.02.25
[백준] 1929 소수 구하기  (0) 2024.02.22
[백준] 1676 팩토리얼 0의 개수  (0) 2024.02.17
[백준] 1654 랜선 자르기  (0) 2024.02.16
[백준] 1181 단어 정렬  (1) 2024.02.09

+ Recent posts