이번에 풀어볼 문제는 난이도 실버 4에 해당하는 문제입니다.
이분탐색에 대해 알고 계신다면 쉽게 풀수 있었던 문제에 해당한다 생각합니다.
문제 링크:https://www.acmicpc.net/problem/1920
풀이방법: 시간제한을 보면 2초입니다. 완전탐색으로 탐색을 해서 풀수 있지만,
이렇게 푼다면 n과 m이 들어갈 수 있는 최대 개수는 100,000이므로
시간 복잡도가 O(n^2)이 되어 시간초과가 발생하게 됩니다. 그럴경우 다른방법을 찾아야 하는데
이때, 생각한 방법이 이분탐색입니다.
이분탐색의 시간 복잡도는 O(log 2 n^2)이됩니다(밑이 2인 로그 n제곱이 됩니다)
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main(){
cin.tie(0);
cout.tie(0);
std::ios::sync_with_stdio(false);
int n,m;
cin>>n;
vector<int>v_n(n);
for(int i=0;i<n;i++){
cin>>v_n[i];
}
//오름차 정렬
sort(v_n.begin(), v_n.end());
cin>>m;
vector<int>v_m(m);
for(int i=0;i<m;i++){
cin>>v_m[i];
}
//찾아야 할 수의 기준으로 for문을 돌린다
for(int i=0;i<v_m.size();i++)
{
bool flag=false;
int lt=0;
//n과 m의 수는 다를수 있음
//rt를 v_n의 크기로 잡아야 한다
//rt를 v_m의 크기로 잡을경우, 틀림
int rt=(int)v_n.size()-1;
int mid=0;
//while문 종료 조건
while(lt<=rt){
mid=(rt+lt)/2;
//mid에 해당하는 v_n의 벡터값이 찾고가 하는 수 보다 작으면
//mid까지는 모두 찾고자 하는 수보다 작은 값들이 들어있다.
if(v_m[i]>v_n[mid]){
lt=mid+1;
}
//위의 경우와 반대
else if(v_m[i]<v_n[mid]){
rt=mid-1;
}
//같을경우 탈출해도 됨
else if(v_m[i]==v_n[mid]){
flag=true;
break;
}
}
if(flag==false){
cout<<0<<"\n";
}
else{
cout<<1<<"\n";
}
}
return 0;
}
처음에 문제를 풀었을때,n과 m의 들어오는 개수가 다를수 있다는 것을 인지하지 못해서 몇번틀렸습니다.
혹시 풀이가 이해가 안되거나 더 좋은 풀이가 있다면 댓글로 남겨주세요 🙋♀️