[BOJ-Code] 1920 - 수 찾기

Posted by DHniyeo Blog on November 30, 2024

문제 링크

💡 이분 탐색/자료 구조/해시를 사용한 집합과 맵/정렬

Memory 2800KB Time 48ms Code Length 740B

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
#include <algorithm>
using namespace std;

int dict_arr[100000];
int find_arr[100000];

int N, M;
void init() {
	cin >> N;
	for (int i = 0; i < N; i++) {
		cin >> dict_arr[i];
	}
	cin >> M;
	for (int i = 0; i < M; i++) {
		cin >> find_arr[i];
	}
	sort(dict_arr, dict_arr + N);
}
int solved(int find_val) {
	int st = 0;
	int en = N - 1;
	while (st<=en) {
		int mid = (st + en) / 2;
		if (dict_arr[mid] < find_val) {
			st = mid+1;
		}
		else if (dict_arr[mid] > find_val) {
			en = mid-1;
		}
		else {
			return 1;
		}
	}
	return 0;
}
int main() {
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	init();
	for (int i = 0; i < M; i++) {
		
		int result = solved(find_arr[i]);
		cout << result << "\n";

	}
}

이 코드는 이진 탐색 알고리즘을 사용하여 주어진 정렬된 배열에서 원하는 값을 찾는 프로그램이다.

init() 함수에서는 입력값을 받고, dict_arr 배열을 정렬한다.

solved() 함수는 이진 탐색을 수행하여 find_val 값을 찾는다.

main() 함수에서는 init() 함수를 호출하고, find_arr 배열의 각 요소에 대해 solved() 함수를 호출하여 결과를 출력한다.


위와 같이 풀었을 때 쉽게 구현 가능하지만, 메모리와 시간이 매우 많이 든다. 즉, 리소스를 많이 잡아먹는다.

그렇기에 좀 더 최적화된 이분 탐색을 이용해보았다.

STL의 upper_bound, lower_bound를 사용하여 찾는 값의 바운더리 값을 바로 찾아서 계산 할 수 있고, 이전에 풀었던 1920-수 찾기 문제의 binary_search 함수를 응용하여 쉽게 풀 수 도있다.

두 함수의 차이는 target과 dict[mid] 값이 같을 때의 경우를 어느 조건문에 같이 넣어 주느냐에 따라 upper_bound 값과 lower_bound 값이 바뀌게 된다. 그리고 while문 조건에 st와 en이 같아진 경우에 더 이상의 변화는 필요 없다. 고로 st와 en이 다를 때 까지만 돌려주면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

vector<int> dict;
vector<int> target;
int N, M;
void init() {
	cin >> N;
	for (int i = 0; i < N; i++) {
		int num;
		cin >> num;
		dict.push_back(num);
	}
	cin >> M;
	for (int i = 0; i < M; i++) {
		int num;
		cin >> num;
		target.push_back(num);
	}
	sort(dict.begin(), dict.end());
}
int upper_bound(int find_val) {
	int st = 0;
	int en = N;
	while (st < en) {
		int mid = (st + en) / 2;
		if (dict[mid] > find_val) {
			en = mid;
		}
		else {
			st = mid + 1;
		}
	}
	return st;
}
int lower_bound(int find_val){
	int st = 0;
	int en = N;
	while (st < en) {
		int mid = (st + en) / 2;
		if (dict[mid] >= find_val) {
			en = mid;
		}
		else {
			st = mid + 1;
		}
	}
	return st;
}

int main() {
	init();

	for (auto a : target) {
		// cout << upper_bound(dict.begin(), dict.end(), a) - lower_bound(dict.begin(), dict.end(), a) << " ";
		cout << upper_bound(a) - lower_bound(a) << " ";
	}
	
}

결과.

(아래 : unordered_map, 위 : 이분 탐색)

0