728x90
문제
베르트랑 공준은 임의의 자연수 n에 대하여, n보다 크고, 2n보다 작거나 같은 소수는 적어도 하나 존재한다는 내용을 담고 있다.
이 명제는 조제프 베르트랑이 1845년에 추측했고, 파프누티 체비쇼프가 1850년에 증명했다.
예를 들어, 10보다 크고, 20보다 작거나 같은 소수는 4개가 있다. (11, 13, 17, 19)
또, 14보다 크고, 28보다 작거나 같은 소수는 3개가 있다. (17,19, 23)
자연수 n이 주어졌을 때, n보다 크고, 2n보다 작거나 같은 소수의 개수를 구하는 프로그램을 작성하시오.
https://www.acmicpc.net/problem/4948
입력
입력은 여러 개의 테스트 케이스로 이루어져 있다.
각 케이스는 n을 포함하는 한 줄로 이루어져 있다.
입력의 마지막에는 0이 주어진다.
출력
각 테스트 케이스에 대해서, n보다 크고, 2n보다 작거나 같은 소수의 개수를 출력한다.
제한
1 ≤ n ≤ 123,456
예제
# input
1
10
13
100
1000
10000
100000
0
# output
1
4
3
21
135
1033
8392
문제 풀이
# 에라토스테네스의 채 활용하여 주어진 범위의 소수 구하기
num = 123456 * 2
is_prime = [True] * (num + 1)
is_prime[0] = is_prime[1] = False
for prime_num in range(2, int(num ** 0.5) + 1):
if is_prime[prime_num]:
for not_prime in range(prime_num * prime_num, num + 1, prime_num):
is_prime[not_prime] = False
primes = [i for i in range(2, num + 1) if is_prime[i]]
while True:
n = int(input())
# 입력 조건에 맞추어 break
if n == 0:
break
cnt = 0
# 출력 조건에 맞추어 prime 개수 count
for prime in primes:
if n < prime <= 2 * n:
cnt += 1
print(cnt)
에라토스테네스의 채는 아래와 같이 작성하였습니다.
# 문제에서 주어진 num 범위
num = 123456 * 2
# 0부터 num까지계산하기 위해 num + 1
is_prime = [True] * (num + 1)
# 0과 1은 소수가 되지 못하기에 False
is_prime[0] = is_prime[1] = False
# 제곱근 이상의 수는 확인할 필요가 없기에 범위 제한
for prime_num in range(2, int(num ** 0.5) + 1):
# prime_num의 배수는 소수가 아니므로 False
if is_prime[prime_num]:
for not_prime in range(prime_num * prime_num, num + 1, prime_num):
is_prime[not_prime] = False
primes = [i for i in range(2, num + 1) if is_prime[i]]
prime_num의 2배수부터 for문을 작성하지 않은 이유는 보다 작은 배수에서 소수로 판명되어 지워졌기 때문입니다.
priem_num이 5라면 5의 2배수, 3배수, 4배수는 앞서 지워졌을 것입니다.
파이썬을 독학하시는 분들에게 도움이 되길 바라며,
혹 더 좋은 방법이 있거나 오류가 있다면 편하게 말씀 부탁드립니다.
728x90