Notice
Recent Posts
Recent Comments
«   2025/06   »
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
Archives
관리 메뉴

일상

[C++] 백준 17103: 골드바흐 파티션 본문

programming

[C++] 백준 17103: 골드바흐 파티션

Mysteryu 2024. 5. 13. 22:17

<풀이>

 

사실 이 문제의 풀이라기 보다는 이 문제에서 무조건 이용해야하는 에라토스테네스의 체 에 대한 풀이이다.

 

소수 관련 문제인데 시간제한이 타이트하면 무조건 에라토스테네스의 체를 생각하면 된다. 이 문제도 에라토스테네스의 체를 이용해서 풀어야 한다.

 

에타로스테네스의 체는 원하는 숫자의 범위 내에 소수를 판별할 수 있는 가장 빠른 방법이다. 가령 [1, 100] 범위 안의 소수를 알고 싶다면, 1에서 100까지의 숫자를 나열한 후 2의배수, 3의배수, 5의 배수, 7의 배수, ... , 10의 배수(100의 제곱근)에 대해서는 소수가 아니라고 표시하면 된다. 4의 배수, 6의 배수, 8의 배수, 9의 배수는 앞에서 2의배수, 3의배수에서 모두 아니라고 표시되므로 굳이 안해줘도 된다. 

 

좀 더 일반적으로 정의하면 1에서 MAX까지의 소수에 대해 판별하고 싶으면 1에서 MAX까지의 수를 나열한 후, 2의 배수부터 MAX 제곱근의 배수에 대해 소수가 아니라고 표시하면 된다.

 

이 문제에서는 MAX가 1000000 이므로 1부터 1000까지의 배수에 대해 소수가 아니라고 표시하면 되며 이는 배열로 간단히 구현할 수 있다. 나머지 부분은 간단하므로 설명을 생략한다.

 

<소스코드>

#include <iostream>
#include <cmath>

int main() {

    int* num = new int[1000001] { 0 }; //소수면 0, 소수가 아니면 1의 값을 가지게 함 

    num[0] = 1;
    num[1] = 1;

    int range = int(std::sqrt(1000000));

    for (int i = 2; i <= range; i++) { //에라토스테네스의 체
        if (num[i] == 1)
            continue;
        else {
            for (int j = 2 * i; j <= 1000000; j += i) {
                num[j] = 1;
            }
        }
    }

    int t; // test case
    std::cin >> t;
    
    int n; // even num
    int p_num = 0; // 파티션 넘버

    for (int c = 0; c < t; c++) {
        std::cin >> n;

        for (int i = 1; i <= n / 2; i++) {
            if (num[i] != 0) // i가 소수가 아니면 넘어감
                continue;
            else { //i가 소수일 때
                if (num[n - i] == 0)
                    p_num++;
            }
        }
        std::cout << p_num << "\n";
        p_num = 0;
    }

    delete[] num;
}

 

 

'programming' 카테고리의 다른 글

[C++] 백준 17298: 오큰수  (1) 2024.05.31
[C++] 백준 1874: 스택 수열  (0) 2024.05.17
[C++] 백준 1212 : 8진수 2진수  (0) 2024.04.27
[C++] 백준 2775 : 부녀회장이 될테야  (1) 2024.04.18
[C++] 백준 2292 : 벌집  (0) 2023.08.02
Comments