문제출처:https://www.acmicpc.net/problem/10816
첫째 줄에 상근이가 가지고 있는 숫자 카드의 개수 N(1 ≤ N ≤ 500,000)이 주어진다. 둘째 줄에는 숫자 카드에 적혀있는 정수가 주어진다.
숫자 카드에 적혀있는 수는 -10,000,000보다 크거나 같고, 10,000,000보다 작거나 같다.
셋째 줄에는 M(1 ≤ M ≤ 500,000)이 주어진다. 넷째 줄에는 상근이가 몇 개 가지고 있는 숫자 카드인지 구해야 할 M개의 정수가 주어지며, 이 수는 공백으로 구분되어져 있다.
M은 -10,000,000보다 크거나 같고, 10,000,000보다 작거나 같다.
특정 원소를 찾는 거라면Binary_search(배열,배열의 크기,element)
로 true,false를 참조하면 된다. 하지만, 이 문제는 10이 3개가 있을 수도 있고 4개가 있을 수도 있는 등, 존재하는 범위의 크기를 알아내야 한다.
이분탐색을 이용해서 해당 숫자가 들어가야할 위치를 찾도록 구현할 수도 있다.(정렬이 깨지지 않게 잘 유지해야한다.) 하지만, 이분탐색 문제는 구현에서 실수를 할 가능성이 매우 높기 때문에, STL을 사용할 수 있다면 STL을 사용하자.
C++은 위와 같이 배열에서 특정원소가 제일 먼저나오는 위치과 제일 마지막에 나오는 위치를 알아낼 수 있는 함수가 있다. lower_bound(배열,배열의크기,원소)
,upper_bound(배열,배열의크기,원소)
Lowerbound는 제일 먼저 나오는 위치값을 반환하고, upperbound는 제일 마지막에 나오는 위치를 반환한다. 따라서, 두 값을 빼면 ? 그 원소의 크기가 나오게 된다.
#include<bits/stdc++.h>
using namespace std;
int N,M;
int cards[500001];
int main(){
cin>>N;
for(int i=0;i<N;i++)
cin>>card[i];
sort(card,card+N);
cin>>M;
int target =0;
for(int i=0;i<M;i++){
cin>>target;
cout<<upper_bound(card,card+N,target)-lower_bound(card,card+N,target)<<'\n';
}
return 0;
}
#include <bits/stdc++.h>
#define fastio cin.tie(0)->sync_with_stdio(0)
using namespace std;
int N, M;
int A[500001];
int B[500001];
int lower_Idx(int target)
{
// 인덱스를 찾는과정.
int st = 0;
int en = N;
while (st < en)
{
int mid = (st + en) / 2;
if (A[mid] >= target)
en = mid;
else
st = mid + 1;
}
return st;
}
int upper_Idx(int target)
{
int st = 0;
int en = N;
while (st < en)
{
int mid = (st + en) / 2;
if (A[mid] > target)
en = mid;
else
st = mid + 1;
}
return en;
}
int main()
{
fastio;
vector<int> ans;
cin >> N;
for (int i = 0; i < N; i++)
{
cin >> A[i];
}
cin >> M;
for (int i = 0; i < M; i++)
{
cin >> B[i];
}
sort(A, A + N);
for (int i = 0; i < M; i++)
{
ans.push_back(upper_Idx(B[i]) - lower_Idx(B[i]));
}
for (auto a : ans)
{
cout << a << " ";
}
return 0;
}