ABOUT ME

컴퓨터 공학과 복전생 복습노트

Today
Yesterday
Total
  • 백준 23820 (MEX) C++
    백준 문제 2022. 1. 14. 19:31
    728x90

    문제

     

    23820번: MEX

    $\textrm{mex}(S)$를 집합 $S$에 포함되지 않은 가장 작은 음이 아닌 정수로 정의한다. 길이가 $n$인 수열 $a_1, a_2, \cdots, a_n$이 주어질 때 $\textrm{mex}\left(\{a_i \times a_j \mid 1 \leq i \leq j \leq n \}\right)$을 구

    www.acmicpc.net

    수열이 주어지면  수열 각각의 원소들의 곱집합에서 없는 숫자중 가장 작은 정수를 출력하면 됩니다.

    예를들어 N이 3이고 수열이 {0, 1, 2} 라면 곱집합은 {0, 1, 2, 4} 가 됩니다. 여기서 없는 숫자중 가장 작은 정수는

    3입니다.

    N의 범위가 1부터 200만 이고 수열 a(i)의 범위 또한 0부터 200만 입니다.

    단순히 모든 수열을 순회하면서 확인하면 O(N^2) 이 이므로 최악의 경우 

    2000000 *2000000 = 40000000000(백억)의 시간복잡도가 나와서 시간초과가 나게 됩니다.

    Brute force방법 밖에 생각이 나지 않아 답이 될 수 없는 경우의 수를 제외 시키기로 했습니다.

     

    1) 먼저 수열 a(i) 에 0이 없다면 답은 바로 0이됩니다. 마찬가지로 a(i)에 1이 없다면 바로 1이 됩니다.

    2) 답은 무조건 2000000이상의 소수중 가장 작은 소수(2000003) 보다 작습니다.

       왜냐하면 1 ≤ a(i) ≤ 2000000 중에서 a(i) * a(j) 는 항상 합성수 입니다. 

       따라서 집합 S에는 항상 합성수만 들어가게 됩니다. 

       그래서 미리 a(i) * a(j)가 2000003을 넘어가면 무시하고 다음으로 넘어가게 됩니다.

     


    전체코드 입니다.

    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
    #include<iostream>
    #include<algorithm>
    #include<climits>
    #include<string>
    #include<vector>
    #include<queue>
    #include<stack>
    #include<deque>
    #include<cmath>
    #include<time.h>
    #include<cstring>
    #include<cmath>
    using namespace std;
    using ll = long long;
    using ull = unsigned long long;
    ll arr[3000000];
    bool check[3000000];
    int main() {
        ios_base::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
        ll n;
        cin >> n;
        for (ll i = 0, a; i < n; i++) {
            cin >> a;
            arr[a]++;
        }
        for (int i = 0; i <= 1; i++) {
            if (!arr[i]) {
                cout << i;
                return 0;
            }
        }
        for (ll i = 1; i <= 2000000; i++) {
            if (!arr[i])continue;
            for (ll j = 1; j <= 2000000; j++) {
                if (i * j > 2000003)break;
                if (!arr[j])continue;
                check[i * j] = true;
            }
        }
        for (int i = 2; i <= 2000003; i++) {
            if (check[i])continue;
            cout << i;
            return 0;
        }
     
      
     
        return 0;
    }
     
    cs

     

Designed by Tistory.