베르트랑 공준
문제
베르트랑 공준은 임의의 자연수 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
1
10
13
100
1000
10000
100000
0
예제 출력 1
1
4
3
21
135
1033
8392
처음에 내가 푼 방식. 실행 시간이 꽤 오래 걸렸다..
do-while문 이용해 0을 받아오기 전까지 반복했다.
N+1과 2N 사이의 수를 하나씩 받아와서 for문을 이용해 2부터 해당 수의 제곱근까지 나눠 떨어지는지를 계산해서 소수 여부를 결정했다.
import java.io.*;
import java.util.Arrays;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
int N = Integer.parseInt(br.readLine());
do {
int cnt = 0;
for (int i = N + 1; i <= 2 * N; i++) {
boolean isPrime = true;
if (i == 1) {
continue;
}
for (int j = 2; j <= Math.sqrt(i); j++) {
if (i % j == 0) {
isPrime = false;
break;
}
}
if (isPrime == true) {
cnt++;
}
}
sb.append(cnt + "\n");
N = Integer.parseInt(br.readLine());
} while (N != 0);
System.out.println(sb);
br.close();
}
}
아래는 다른 분들 코드를 참조해서 푼 방식.
삼중 반복문을 피하기 위해 N과 2N 사이의 소수를 구하는 코드는 함수로 따로 뺐다.
함수 계산식은 저번 포스팅에서의 계산식과 비슷하다.
2N+1크기의 배열을 만들고, 2부터 2*N의 제곱근 까지 수를 받아와서 해당 수의 배수에는 모두 false 값을 담아주었다.
그리고 해당 범위에서 true 값을 가진 요소의 수를 반환해서 String builder에 추가시켰다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
while (true) {
int N = Integer.parseInt(br.readLine());
if (N == 0) {
break;
}
if (N == 1) {
sb.append("1\n");
} else {
sb.append(calcPrime(N) + "\n");
}
}
System.out.println(sb);
br.close();
}
public static int calcPrime(int N) {
int cnt = 0;
boolean[] isPrime = new boolean[2 * N + 1];
Arrays.fill(isPrime, true);
for (int i = 2; i <= Math.sqrt(2 * N); i++) {
if (isPrime[i] == true) {
for (int j = i * i; j < isPrime.length; j += i) {
isPrime[j] = false;
}
}
}
for (int i = N + 1; i <= 2 * N; i++) {
if (isPrime[i] == true)
cnt++;
}
return cnt;
}
}
'6. 자료구조 & 알고리즘 > 6-2. 백준' 카테고리의 다른 글
백준 - [2793번: 블랙잭] (0) | 2022.06.23 |
---|---|
백준 - [2447번: 별 찍기 - 10] (0) | 2022.06.21 |
백준 - [1929번: 소수 구하기] (0) | 2022.06.19 |
백준 - [11653번: 소인수분해] (0) | 2022.06.19 |
백준 - [1978번: 소수 찾기] (0) | 2022.06.19 |