1 분 소요

1. 최대공약수(GCD)

두 정수 a,b의 공약수는 a의 약수이자 b의 약수인 정수이다.
최대공약수(GCD, Great Common Divisor)는 가장 큰 공약수를 말한다.

GCD(a,b,c) = GCD(GCD(a,b), c)
세 수, 그 이상 N개의 숫자의 최대공약수는 위와 같은 식으로 구할 수 있다.

2 최대공약수 구하는 방법

2.1 Brute Force

2부터 min(a,b)까지 나눠보기 (Brute Force)

1
2
3
4
5
6
7
int gcd = 1;
for(int i=2; i<=min(a,b); i++){
    if(a%i == 0 && b%i ==0){
        gcd = i;
        break;
    }
}

2.2 소인수 분해 (prime factorization)

두 수를 소인수분해 해서 중복되는 부분을 찾으면 최대공약수가 된다.
예를 들어 a = 192, b = 72라고 하면
$192 = 2^6 X 3$
$72 = 2^3 X 3^2$
$\therefore GCD(192,72) = 2^3 X 3 = 24$
이런 식으로 구할 수 있다.
문제는 소인수분해를 하는게 번거롭고 느리다.

2.3 유클리드 호제법(Euclidean algorithm)

a를 b로 나눈 나머지를 r이라고 했을 때 (단 a > b), GCD(a,b) = GCD(b,r)임을 이용하면 빠르게 구할 수 있다. 나머지가 0이 될 때까지 진행하면 최대공약수를 구할 수 있다.

1
2
3
4
5
6
int gcd(int a, int b){
    if(b == 0)
        return a;
    else
        return gcd(b, a%b);
}

재귀 함수를 사용하면 위와 같이 나타낼 수 있고 재귀 버전은 호출스택이 쌓이기 때문에 메모리를 더 사용한다.

1
2
3
4
5
6
7
8
int gcd(int a, int b){
    while(b != 0){
        int r = a%b;
        a = b;
        b = r;
    }
    return a;
}

반복문으로 만든 최대공약수 함수이다. 시간복잡도는 $O(log_(a+b))$이다.

3. 최소공배수

두 정수 a,b의 공배수는 a와 b 모두의 배수가 되는 정수입니다.
최소공배수(LCM, Least Common Multiple)는 가장 작은 공배수를 말한다.

LCM(a,b,c) = LCM(LCM(a,b),c)
세 수, 그 이상 N개의 숫자의 최소공배수는 위와 같은 식으로 구할 수 있다.

4. 최소공배수 구하는 방법

최소 공배수는 위에서 구한 최대공약수를 활용해 구할 수 있다.

\(LCM(a,b) = \frac{a \times b}{GCD(a,b)}\) 두 수의 곱을 최대공약수로 나눠주면 최소공배수가 된다.

1
2
3
int lcm(int a, int b){
    return (a*b) / gcd(a,b);
}

Ref.