백준 1920 수 찾기

hyoJeong·2021년 5월 19일
0

이번에 풀어볼 문제는 난이도 실버 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의 들어오는 개수가 다를수 있다는 것을 인지하지 못해서 몇번틀렸습니다.
혹시 풀이가 이해가 안되거나 더 좋은 풀이가 있다면 댓글로 남겨주세요 🙋‍♀️

0개의 댓글