DY의 세상구경
실력키우기 소수의개수(JAVA) 본문
2813 : 소수의 개수
제한시간: 1ms 메모리제한: 128MB
해결횟수: 382회 시도횟수: 1558회
소수(prime number)란 1보다 큰 자연수 중 1과 자기 자신 두 개만을 약수로 갖는 수를 말한다.
자연수 M과 N을 입력받아 M부터 N까지 소수의 개수를 구하여 출력하는 프로그램을 작성하시오.
![]() 10 100 | ![]() 21 |
- /**************************************************************
- Problem: 2813
- User: a132034
- Language: Java
- Result: Success
- Time:1220 ms
- Memory:16684 kb
- ****************************************************************/
- import java.util.Scanner;
- public class Main
- {
- public static void main(String[] args) {
- final int UNDEFINE = 0;
- final int PRIME = 1;
- final int NOT = 2;
- boolean minFlg = true;
- arr[1] = NOT;
- {
- boolean isPrime = true;
- if(arr[i] == UNDEFINE)
- {
- for(int j = 2; j*j < i; ++j)
- if(i % j == 0)
- isPrime = false;
- if(isPrime){
- arr[i] = PRIME;
- }
- arr[j] = NOT;
- }
- }
- }
- {
- if(arr[i] == PRIME)
- count ++;
- }
- }
- }
바로 이전 포스팅인 소수구하기를 그대로 적용시켜보았다.
결과는 7개정도 통과, 나머지 타임아웃.
도움말을 보며 원인 분석을 시작..
도움말을 보다 보니 내 코드와 결정적으로 다른 두 가지를 알게 됨.
1. 기존의 코드에서는 모든 수를 돌며 모든 수의 배수를 소수가 아닌 것으로 해 주었음
-> 해당하는 수의 이전까지는 모두 이미 걸러내어져 있기 때문에 중복하는 경우가 생김
ex) 2일 때 걸러낸 경우 -> 4, 6, 8, 10... 을 모두 걸러냄
이후 3일 때 걸러내는 경우 -> 6, 9, 12.. 중 6은 이미 위에서 걸러내었기 때문에 중복된 경우가 생김.
이를 확인해 보면 i일 때 i*i의 전 까지 (3일 때 3*3 = 9)는 이미 걸러내어져 있다.
이유는 j를 걸러낼 때에 j보다 작은 수를 곱해서 나오는 값들은 이미 걸러져 있기 때문.
ex) 10을 걸러낼 때에 10*9, 10*8, 10*7 ... 10*2 는 모두 2, 3, 4, 5, 6, 7, 8, 9에서 걸러내졌기 때문.
때문에 걸러낼 때 해당 수의 배수부터 시작해서 걸러내 준다.
-> 이는 결국 해당 수의 배수가 max값이 되기 전 까지만 실행하면 된다는 결론을 얻을 수 있다.
ex) 1부터 2500까지를 구할 경우
50의 제곱(50*50)은 2500이므로 50이후의 숫자부터는 걸러낼 필요가 없다.
2. 두 번째로
for
(
int
j =
2
; j*j < i; ++j)
소수를 체크하는 루프의 조건을 j < i 에서 j*j < i로 바꾸었다.
이는 j*j > i 가 되는 j부터는 체크할 필요가 없다는 말인데
이 식은 잘 이해를 못하겠어서 찾아보았더니..
이미 수학에서 증명된 공식이라고 한다.
소수는 1과 자기자신을 제외한 수의 배수가 아니어야 하기 때문에 현재값 i를 확인 할 때 이 수보다 작은 수들로 나누어서 떨어지면 소수가 아닌것이다. 라는게 기본적인 소수의 정의이지만
루트i 까지만 나누어서 나누어 떨어지면 소수가 아니라고 수학적으로 증명되었다.
'IT > ALGORITHM' 카테고리의 다른 글
실력키우기 문자열변환(JAVA) (7) | 2016.06.03 |
---|---|
실력키우기 소수와 합성수(JAVA) (0) | 2016.06.03 |
실력키우기 소수(JAVA) (0) | 2016.06.01 |
알고리즘 로봇(JAVA) (0) | 2016.05.26 |
실력키우기 최대공약수, 최소공배수(JAVA) (0) | 2016.05.25 |