개념

두 자연수를 모두 나누어떨어지게 하는 가장 큰 수가 최대공약수(GCD)입니다. 두 수의 공통 배수 중 가장 작은 자연수가 최소공배수(LCM)입니다.

2424개와 1818개를 각각 같은 크기의 묶음으로 남김없이 나누려면, 묶음의 크기는 두 수의 공약수여야 합니다. 가장 큰 묶음의 크기가 최대공약수입니다. 2424번마다 일어나는 일과 1818번마다 일어나는 일이 동시에 다시 일어나는 주기를 구할 때는 최소공배수를 사용합니다.

유클리드 호제법

큰 수를 작은 수로 나눈 나머지로 문제를 줄입니다. aa를 bb로 나눈 몫이 qq, 나머지가 rr이면 a=bq+ra=bq+r입니다.

  • aa와 bb의 공약수는 a−bq=ra-bq=r도 나눕니다.
  • 반대로 bb와 rr의 공약수는 bq+r=abq+r=a도 나눕니다.

따라서 (a,b)(a,b)와 (b,r)(b,r)의 공약수가 같으므로 gcd⁡(a,b)=gcd⁡(b,a mod b)\gcd(a,b)=\gcd(b,a\bmod b)입니다. 이 변환을 반복하면 나머지가 점점 작아집니다. 나머지가 00이 되면 앞의 수가 뒤의 수로 나누어떨어지므로 마지막으로 나눈 수가 최대공약수입니다.

2424와 1818은 24 mod 18=624\bmod18=6, 18 mod 6=018\bmod6=0이므로 최대공약수가 66입니다.

최소공배수

최대공약수를 gg라고 하면 a=gxa=gx, b=gyb=gy로 나타낼 수 있습니다. 공통 인수를 모두 gg로 꺼냈으므로 xx와 yy의 최대공약수는 11입니다. 두 수의 배수가 되려면 공통 부분 gg와 나머지 인수 x,yx,y를 모두 포함해야 하므로 최소공배수는 gxygxy입니다.

두 수를 그대로 곱한 ab=g2xyab=g^2xy에는 공통 부분 gg가 한 번 더 들어 있습니다. 따라서 gg로 한 번 나누면 됩니다.

lcm⁡(a,b)=abgcd⁡(a,b).\operatorname{lcm}(a,b)=\frac{ab}{\gcd(a,b)}.

24=6×424=6\times4, 18=6×318=6\times3이므로 최소공배수는 6×4×3=726\times4\times3=72입니다.

복잡도

입력한 두 자연수를 a,ba,b라고 합니다.

연산시간복잡도추가 공간
반복 호제법·최소공배수O(log⁡min⁡(a,b))O(\log\min(a,b))O(1)O(1)

예제

문제

두 양의 정수의 최대공약수와 최소공배수를 구하여라.

입력

첫째 줄에 두 양의 정수 A,BA,B가 공백을 사이에 두고 주어진다. 1≤A,B≤1 0001\le A,B\le1\,000이다.

출력

최대공약수와 최소공배수를 공백으로 구분하여 출력한다.

예제 입력

24 18

예제 출력

6 72

예제 코드

C++20

#include <iostream>

using namespace std;

int main() {
    int a, b, x, y, r;

    cin >> a >> b;
    x = a;
    y = b;
    while (y != 0) {
        r = x % y;
        x = y;
        y = r;
    }

    cout << x << ' ' << a / x * b << '\n';
}