소수란?
소수(prime) 는 1과 자기 자신으로만 나누어지는, 1보다 큰 정수입니다(2, 3, 5,
7, 11, ...). "이 수가 소수인가?"를 빠르게 판단하는 법을 배웁니다.
1. 가장 단순한 방법
\(N\)이 2부터 \(N-1\)까지의 어떤 수로도 나누어지지 않으면 소수입니다.
bool isPrime(int n) {
if (n < 2) return false;
for (int i = 2; i < n; i++)
if (n % i == 0) return false; // 약수 발견 -> 소수 아님
return true;
}
맞지만 \(O(N)\)이라 큰 수에선 느립니다.
2. 핵심 통찰: √N까지만 보면 된다
\(N\)이 \(a \times b\)로 쪼개진다면, \(a\)와 \(b\) 중 하나는 반드시 \(\sqrt{N}\) 이하입니다.
(둘 다 \(\sqrt N\)보다 크면 곱이 \(N\)을 넘으니까요.) 따라서 \(\sqrt N\)까지만 나눠
봐서 약수가 없으면 소수입니다.
bool isPrime(int n) {
if (n < 2) return false;
for (int i = 2; (long long)i * i <= n; i++) // i*i <= n <=> i <= √n
if (n % i == 0) return false;
return true;
}
i <= sqrt(n) 대신 i * i <= n 으로 쓰는 게 정확하고 안전합니다(실수 오차 회피).
이로써 \(O(N)\)이 \(O(\sqrt N)\)으로 확 줄어듭니다.
3. 복잡도 비교
| 방법 | 복잡도 | \(N = 10^9\)일 때 |
|---|---|---|
| 2 ~ N-1 | \(O(N)\) | 약 10억 번 (느림) |
| 2 ~ √N | \(O(\sqrt N)\) | 약 3만 번 (빠름) |
수 하나의 소수 판정이라면 \(\sqrt N\) 방법으로 충분합니다.
4. 여러 수를 판정해야 한다면?
"1부터 N까지 각 수가 소수인지"처럼 범위 전체를 묻는다면, 하나씩 \(\sqrt N\)로
하는 것보다 에라토스테네스의 체가 훨씬 빠릅니다(다음 단계에서 별도 단원).
지금은 "수 하나 판정 = √N 방법"을 확실히 익히세요.
정리
- 소수 = 1과 자기 자신만 약수인 1 초과 정수.
- 1 이하는 소수 아님, 2는 가장 작은 소수.
- \(\sqrt N\)까지만 나눠 보면 충분 —
i * i <= n. - 범위 전체를 묻는다면 체가 더 빠르다.