BOJ - 1081 - 숫자 카드
문제
문제 개념
문제
- 숫자 카드는 정수 하나가 적혀져 있는 카드이다. 상근이는 숫자 카드 N개를 가지고 있다. 정수 M개가 주어졌을 때, 이 수가 적혀있는 숫자 카드를 상근이가 몇 개 가지고 있는지 구하는 프로그램을 작성하시오.
입력
- 첫째 줄에 상근이가 가지고 있는 숫자 카드의 개수 N(1 ≤ N ≤ 500,000)이 주어진다. 둘째 줄에는 숫자 카드에 적혀있는 정수가 주어진다. 숫자 카드에 적혀있는 수는 -10,000,000보다 크거나 같고, 10,000,000보다 작거나 같다.
- 셋째 줄에는 M(1 ≤ M ≤ 500,000)이 주어진다. 넷째 줄에는 상근이가 몇 개 가지고 있는 숫자 카드인지 구해야 할 M개의 정수가 주어지며, 이 수는 공백으로 구분되어져 있다. 이 수도 -10,000,000보다 크거나 같고, 10,000,000보다 작거나 같다.
구현
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
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
int main()
{
ios_base :: sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int A_num, M_num;
cin >> A_num;
int A[A_num];
for(int i=0; i < A_num; i++)
cin >> A[i];
// 기준 리스트 오름차순 정렬
sort(A, A + A_num);
cin >> M_num;
int answer[M_num];
for(int i=0; i < M_num; i++)
{
int temp;
cin >> temp;
// 이진탐색을 통한 존재유무 탐색 때문에 오름차순 정렬이 필요.
int cnt = upper_bound(A, A + A_num, temp) - lower_bound(A, A + A_num, temp);
answer[i] = cnt;
}
for(int i=0; i < M_num; i++)
cout << answer[i] << " ";
return 0;
}
SOL
- lower_bound
- 찾으려는 요소와 같거나 초과하는 index를 반환함.
- upper_bound
- 찾으려는 요소를 초과하는 첫번째 index를 반환함.
- 위 특성을 이용하면, 두 index의 차는 찾으려는 요소의 중복된 개수를 구할 수 있다.
- 찾으려는 값 [ 10 ]
- 확인 리스트 [ 1 2 3 10 10 10 ]
- lower_bound : 3
- upper_bound : 6
- [ 10 ]의 개수 : abs(lower_bound - upper_bound)