에라토스테네스의 체
→ **O(N) ****최적화된 방법 (제곱근까지만 탐색) → O(N log log N)
037 소수 구하기
038 거의 소수 구하기
039 소수 & 팰린드롬 수 중에서 최소값 찾기
040 제곱이 아닌 수 찾기
2^2, 3^2, ..., sqrt(max)^2까지의 제곱수를 기준으로
각 제곱수에 대해 [min, max]범위에서 해당 제곱수의 배수들을 true로 체크
check 배열에서 flase인 값들의 개수를 세면, 그것이 ‘제곱이 아닌 수’의 개수
1부터 N까지의 정수 중에서 N과 서로소인 자연수의 개수를 의미
계산 원리
1부터 N까지의 수를 배열에 저장한다.
배열에서 소수의 배수들을 순차적으로 지워가며 계산한다.
(에라토스테네스의 체 방식과 유사)
소수 p를 만날 때마다 배열[k] = 배열[k]-배열[k] / p를 적용한다.
즉, φ(N) = N × (1 - 1/p₁) × (1 - 1/p₂) × ...
→ 여기서 p₁, **p₂, …**는 N의 서로 다른 소인수들
N = 15
초기: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 → 총 15개
2의 배수 제거 → 2 4 6 8 10 12 14 제거
3의 배수 제거 → 3 6 9 12 15 제거
5의 배수 제거 → 5 10 15 제거
→ 남은 수: 1, 7, 11, 13 (15와 서로소)
→ φ(15) = 8
수학적 공식
어떤 수 N이 소인수 분해되어
N = p₁^a₁ * p₂^a₂ * ... * pₖ^aₖ 이면
φ(N) = N × (1 - 1/p₁) × (1 - 1/p₂) × ... × (1 - 1/pₖ)
041 오일러 피 함수 구현하기
1 ≤ k ≤ n중에서 n과 서로소인 수의 개수
⇒ 서로소가 아닌 수들은 소수 p의 배수이기 때문에 그만큼을 빼주는 방식으로 구함
result = n으로 초기화
2부터 sqrt(n)까지의 소수 p에 대해
반복 끝나고 n > 1이라면 마지막 남은 소인수 존재
두 수의 최대공약수(GCD)를 빠르고 효율적으로 구하는 알고리즘
GCD(Greatest Common Divisor)
큰 수를 작은 수로 나눠서 나온 나머지를 계속 나누는 방식
큰 수를 작은 수로 MOD 연산 (나머지 구하기)
이전 단계의 작은 수를 큰 수로 나머지를 작은 수로 바꿔서 다시 반복
나머지가 0이 되면 그때의 작은 수가 바로 최대공약수(GCD)!
gcd(a, b) = gcd(b, a % b) → a % b == 0이면 b가 최대공약수!
def gcd(a, b):
if b == 0:
return a
return gcd(b, a % b)
042 최소공배수 구하기
최소공배수 공식: LCM(A, B) = (A * B) / GCD(A, B)
최대공약수(GCD) 구하는 법: 유클리드 호제법
gcd(a, b) = gcd(b, a % b) b가 0이면 gcd는 a
043 최대 공약수 구하기
044 칵테일 만들기