본문 바로가기
알고리즘/기초수학

[java 백준] 실버 2/1929번 소수 구하기

by Meaning_ 2021. 9. 16.
728x90
반응형

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

 

1929번: 소수 구하기

첫째 줄에 자연수 M과 N이 빈 칸을 사이에 두고 주어진다. (1 ≤ M ≤ N ≤ 1,000,000) M이상 N이하의 소수가 하나 이상 있는 입력만 주어진다.

www.acmicpc.net

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import java.io.IOException;
import java.util.Scanner;
 
public class Main {
 
    public static void main(String[] args) throws IOException {
        Scanner sc = new Scanner(System.in);
        int M = sc.nextInt();
        int N = sc.nextInt();
        int[] arr = new int[N + 1];
        for (int i = 2; i <= N; i++) {
            arr[i] = i;
        }
        for (int i = 2; i <= N; i++) {
            if (arr[i] == 0) {
                continue;
            }
            for (int j = i + i; j <= N; j += i) {
 
                arr[j] = 0;
            }
 
        }
        for (int i = M; i <= N; i++) {
            if (arr[i] != 0) {
                System.out.println(arr[i]);
            }
        }
 
    }
 
}
cs

 

 

소수구하기 문제는 에라토스테네스의 체를 이용하면 시간초과 걸리지 않고 풀어낼 수 있다!

 

알고리즘을 구현할 때 참고한 사이트는

https://marobiana.tistory.com/91

 

[C++] 소수 구하기 최적의 알고리즘 (2) - 에라토스테네스의 체

소수 구하기 최적의 알고리즘 1편에서 (http://marobiana.tistory.com/89) 주어진 수보다 작은 수의 소수들로 나누는게 성능이 좋다고 했었는데, 그것보다 더 좋은 알고리즘을 찾아냈다.ㅋㅋ 이것보다

marobiana.tistory.com

 

풀면서 중요하다 생각한 부분은

1) 반복문의 시작을 2부터 해줘야한다.

그래야 M부터 N까지 소수만 정확히 골라낼 수 있다. 그냥 M부터 해주게 되면 2부터 M-1까지 숫자들 중 1과 자기자신을 제외한 약수를 포함한 수가 있을 수도 있기 때문이다!

2)

for (int j = i + i; j <= N; j += i) {

 

                arr[j] = 0;

            }

 

--> j가 2i 부터 시작되는게 중요하다. 안그러면 3이나 5같은 비교적 앞부분에 있는 소수들이 잘리게 된다..ㅜㅜ

그러면 의문이 생길 수도 있다. j가 2i부터 시작하면 2i 이전에 소수가 아닌 수들을 어떻게 판별하는가..?

 

예를 들어 i가 2면 j는 4부터 시작한다. arr[4],arr[6] .. 모두 합성수이기 때문에 0으로 바뀐다.

i가 3이면 j인 6,9,12... 는 0으로 바뀐다. 

i가 4이면(이미 4는 합성수여서 0이 됐고) j는 8,12,16.. 인데 어차피 얘네는 다 0으로 이미 바뀌어있다.

 

이렇게 2i부터 시작해도 합성수이면 이미 앞에서 다 0으로 바뀌기 때문에 걱정할 필요 없다. 

728x90
반응형

댓글