[BOJ][⚪2][백준#04948] 베르트랑 공준

작성:    

업데이트:

카테고리:

태그: , , ,

문제 출처

BAEKJOON Online Judge #4948


문제

베르트랑 공준은 임의의 자연수 n에 대하여, n보다 크고, 2n보다 작거나 같은 소수는 적어도 하나 존재한다는 내용을 담고 있다. 이 명제는 조제프 베르트랑이 1845년에 추측했고, 파프누티 체비쇼프가 1850년에 증명했다. 예를 들어, 10보다 크고, 20보다 작거나 같은 소수는 4개가 있다. (11, 13, 17, 19) 또, 14보다 크고, 28보다 작거나 같은 소수는 3개가 있다. (17,19, 23) 자연수 n이 주어졌을 때, n보다 크고, 2n보다 작거나 같은 소수의 개수를 구하는 프로그램을 작성하시오. 


입력

입력은 여러 개의 테스트 케이스로 이루어져 있다. 각 케이스는 n을 포함하는 한 줄로 이루어져 있다. 입력의 마지막에는 0이 주어진다.


출력

각 테스트 케이스에 대해서, n보다 크고, 2n보다 작거나 같은 소수의 개수를 출력한다.


제한

1 ≤ n ≤ 123,456


예제

입력

1
10
13
100
1000
10000
100000
0


출력

1
4
3
21
135
1033
8392


My Sol

import sys
input = sys.stdin.readline

n = 123456
v = [1]*(n*2+1)
for i in range(2, n*2+1):
    if v[i]:
        for j in range(i+i, n*2+1, i):
            v[j] = 0

v2 = [0]*(n*2+1)
for i in range(1, n*2+1):
    v2[i] = v2[i-1]+v[i]

while True:
    N = int(input())
    if not N: break
    print(v2[N*2]-v2[N])

소수의 정의를 이용해 2부터 시작하여 체크가 되지 않은 수를 마주한다면 해당 수의 배수들을 범위 내에서 모두 소수가 아니라 체크한다. 이렇게 체크를 해나가면 1인 것은 소수, 아닌 것은 0이 된다. 이를 123456의 2배까지 체크한다.

그리고 구간에서 소수의 개수이므로 카운드정렬의 누적합을 사용하여 바로 빼내어 체크할 수 있도록 하였다. 이렇게 되면 n이 몇 개가 되든 처음에 소수리스트만 만들어내면 O(1)의 시간복잡도로 답을 낼 수 있다.


결과

맞았습니다!!

댓글남기기