< [C++/백준 4948번] 베르트랑 공준

프로그래밍 공부/백준 (C++)

[C++/백준 4948번] 베르트랑 공준

Rocketbabydolls 2024. 1. 28. 11:20

https://www.acmicpc.net/problem/4948

 

4948번: 베르트랑 공준

베르트랑 공준은 임의의 자연수 n에 대하여, n보다 크고, 2n보다 작거나 같은 소수는 적어도 하나 존재한다는 내용을 담고 있다. 이 명제는 조제프 베르트랑이 1845년에 추측했고, 파프누티 체비쇼

www.acmicpc.net

 

해결 방법

  소수 판별법으로 N에서 2N까지의 범위의 수를 전부 소수 판별을 하면 시간 초과가 일어난다. 

에라토스테네스의 체를 이용해서 미리 선언되어있는 배열에 소수들을 판별해 놓아서 소수의 개수만 세주면 해결된다.

 

에라토스테네스의 체를 이용하는 방법은

루트 N < N 범위까지만의 본인을 제외한 배수들을 전부 지워주는 것이다.

 

2를 제외한 2의 배수 삭제
3을 제외한 3의 배수 삭제

4는 2에서 지워졌으므로 생략

5를 제외한

.

.

.

 

N이 100이라면 10의 배수까지 지워주게 되고, 11 > 루트 100 이므로 중단한다.

 

 

시행 착오

  범위가 N부터 2N (1 <= N <= 123456) 이라는 사실을 망각해 배열의 크기를 123456으로 선언했다가 segmentation error 를 띄웠다. 배열의 크기를 두배 해 주니 문제없이 작동했다.

 

 

소스 코드

#include <iostream>
#include <algorithm>
using namespace std;

int arr[246913];

bool IsPrime(long long input)
{
   long long num = input;

    if(num <= 1) return false;
    if(num == 2 || num == 3) return true;
    if(num % 2== 0 || num % 3 == 0) return false;

    for(long long i = 5; i * i <= num ;i++)
    {
        if(num % i == 0) return false;
    }

    return true;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
  
    long long N;

    
    for(int i = 1 ; i < 246913 ; i++)
    {
        arr[i-1] = i;
    }


    arr[0] = 0;
  
    for(int j = 2; j * j < 246913 ; j++)
    {
        for(int i = 1 ; i < 246913 ; i++)
        {
            if(arr[i] == 0) continue;

            if(arr[i] % j == 0 && (i+1 != j)) arr[i] = 0; 
        }
    }

    while(1)
    {
        cin >> N;  
        if( N == 0) break;

        int cnt = 0;
        for(int i = N+1 ; i <= N*2 ; i++)
        {
            if(arr[i-1] != 0) cnt++;
        }

        cout << cnt << '\n';
    }

    return 0;
}