본문 바로가기

개발(합니다)/알고리즘&코테

알고리즘 단계별로 풀어보기 : BOJ-4948(베르트랑공준)

반응형

문제(출처)

베르트랑 공준은 임의의 자연수 n에 대하여, n보다 크고, 2n보다 작거나 같은 소수는 적어도 하나 존재한다는 내용을 담고 있다.


이 명제는 조제프 베르트랑이 1845년에 추측했고, 파프누티 체비쇼프가 1850년에 증명했다.


예를 들어, 10보다 크고, 20보다 작거나 같은 소수는 4개가 있다. (11, 13, 17, 19) 또, 14보다 크고, 28보다 작거나 같은 소수는 3개가 있다. (17,19, 23)


n이 주어졌을 때, n보다 크고, 2n보다 작거나 같은 소수의 개수를 구하는 프로그램을 작성하시오. 


입력

입력은 여러 개의 테스트 케이스로 이루어져 있다. 각 케이스는 n을 포함하며, 한 줄로 이루어져 있다. (n ≤ 123456)


입력의 마지막에는 0이 주어진다.


출력

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


예제 입력

1

10

13

100

1000

10000

100000

0


예제 출력

1

4

3

21

135

1033

8392



내 풀이

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;

public class Main {
// 주어진 수의 n부터 2n까지의 소수를 구하라
// n <=123456
    
    public static void main(String args[]) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        
//      int[] num = {1, 10, 13, 100, 1000, 10000, 100000};
        String check = "";
        Queue<Integer> q = new LinkedList<>();
        while(!(check = br.readLine()).equals("0")) {
            q.add(Integer.parseInt(check));
        }
        
        int[] num = new int[q.size()];
        for(int i= 0; i < num.length; i++) {
            num[i] = q.poll();
        }
        
        
        // 최대 값 찾기
        int max = 0;
        for(int i = 0; i < num.length; i++) {
            if(max < num[i]) {
                max = num[i];
            }
        }
        max = max * 2;
        // 소수만 체크하기 1은 소수 아니고 0은 소수
        int[] arr = new int[max+1];
        for(int i = 2; i <= max+1; i++) {
            for(int j = 2; j * i <= max; j++) {
                arr[j*i] = 1;
            }
        }
        arr[0] = 1;
        arr[1] = 1;
        int[] count = new int[num.length];
        for(int i = 0; i < num.length; i++) {
            int n = num[i] + 1;
            for(int j = n; j < (2 *n) -1; j++) {
                if(arr[j] == 0) {
                    count[i]++;
                }
            }
        }
        
        for(int i = 0; i < count.length; i++) {
            bw.write(String.valueOf(count[i]));
            bw.newLine();
        }
        bw.close();
    }
}


내 풀이 해석

동적계획법으로 문제를 해결하는 방법입니다.
0이 나올때까지 큐 링크드리스트에 입력 값을 받아서 저장합니다.
저장한 값을 배열에 저장하고 최고 값을 찾아 저장합니다.
최고 값까지 소수가 아닌 값들은 1로 표시하고 소수 인 값은 0으로 표시합니다.
n보다 1큰 값부터 2*n까지의 배열 중 0인 값을 찾아 카운팅하고 출력합니다.


반응형