728x90
728x90
최대 공약수(GCD)와 최소 공배수(LCM) ; 유클리드 호제법(Euclidean Algorithm)
최대 공약수(GCD; Greatest Common Divisor(Factor))
- 두 개 이상의 자연수들의 공통인 약수들의 모임을 공약수(Common Divisor)라고 하고, 공약수 중에서 가장 큰 수를 최대 공약수(Greatest Common Divisor)라고 한다.
- 예) 의 약수는 이고 의 약수는 일 때, 두 수 와 의 공약수는 이고 최대 공약수는 이 된다.

코드
int gcd(int x, int y) { for (int i = (x > y ? y : x); i >= 1; i--) { // 두 수의 최댓값부터 시작해서 1까지 if (x % i == 0 && y % i == 0) { // 두 수로 나누어 떨어질 경우 return i; } } }
- 두 개의 정수 x와 y의 최대 공약수는 x와 y의 최솟값보다 클 수가 없기 때문에 for 문의 초기부 i는 두 개의 정수 x와 y 중에서 최솟값으로 초기화하고 초깃값부터 1까지 회전한다.
- 두 개의 정수 x와 y를 동시에 나눌 수 있는 첫 번째 정수가 두 수 x와 y의 가장 큰 공약수이므로, 첫 번째로 조건문을 만족하는 정수 i는 최대 공약수가 된다.
유클리드 알고리즘(Euclidean Algorithm) ; 유클리드 호제법

- 유클리드 알고리즘(Euclidean Algorithm) 또는 유클리드 호제법은 2개의 자연수의 최대 공약수(GCD)를 구하는 알고리즘이다.
- 유클리드(Euclid, BC330? ~ BC275?)가 기원전 300년 경에 쓴 『원론』 제 7권에 나오는 가장 오래된 알고리즘이다.
- "두 개의 자연수 A와 B에 대해서 A를 B로 나눈 나머지를 R이라고 하면(단, A ≥ B) A와 B의 최대 공약수는 B와 R의 최대 공약수와 같다."
- 이 성질을 이용하여 B를 R로 나눈 나머지 R1을 구하고, 다시 R을 R1으로 나눈 나머지 R2를 구하고, 다시 R1을 R2로 나눈 나머지를 구하는 과정을 반복하다가 나머지가 0이 되었을 때 이 때 나누는 수 제수가 A와 B의 최대 공약수가 된다는 알고리즘이다.
그림으로 이해하기
- 8개의 상자가 놓여 있는 A 그룹과 3개의 상자가 놓여있는 B 그룹이 있을 때, 두 그룹 A와 B는 모두 1개의 상자의 배수이므로 두 그룹 A와 B의 최대 공약수는 1개의 상자가 된다.

- A와 B 그룹은 둘 다 최대 공약수가 1개의 상자이므로, 1개의 상자의 배수이다.
- A 그룹을 B 그룹으로 나눈 나머지는 2개의 상자가 나오고, 이 2개의 상자는 A 그룹에 있었던 상자이므로 나머지로 나온 2개의 상자도 최대 공약수인 1개의 상자의 배수가 된다.
- 다시 3개의 상자가 A 그룹이 되고, 나머지 2개의 상자가 B 그룹이 되어 같은 연산을 한다.

- A와 B 그룹은 둘 다 최대 공약수인 1개의 상자의 배수의 배수이다.
- A 그룹을 B 그룹으로 나눈 나머지는 1개의 상자가 나오고, 이 1개의 상자는 A 그룹에 있었던 상자이므로 나머지로 나온 1개의 상자도 최대 공약수인 1개의 상자의 배수가 된다.
- 다시 2개의 상자가 A 그룹이 되고, 나머지 1개의 상자가 B 그룹이 되어 같은 연산을 한다.

- A와 B 그룹은 둘 다 최대 공약수인 1개의 상자의 배수의 배수이다.
- A 그룹을 B 그룹으로 나누면 나머지는 0개의 상자가 나오고, B 그룹에 있던 1개의 상자가 지금까지 나누었던 모든 상자 그룹들을 나눌 수 있는 최대 상자이므로 마지막으로 남은 이 1개의 상자가 최대 공약수가 되는 것이다.
- 이것을 수학적으로 증명하면 다음과 같다.
수학적으로 증명하기
- 두 수 와 가 주어졌을 때 (단, ), 두 수 A와 B의 최대 공약수를 라고 하면 다음과 같이 나타낼 수 있다.
- 를 로 나눈 몫을 라고 하고 나머지를 이라고 한다면 다음과 같이 나타낼 수 있다.
- 여기서 와 의 최대 공약수가 임을 증명하면 된다.
- 이고, 가 된다.
- 따라서 와 의 공약수는 가 되는데, 와 가 서로소임을 증명하면 공약수 는 최대 공약수가 된다.
- 와 가 서로소임은 귀류법을 써서 증명할 수 있다.
|
- 와 는 서로소이기 때문에 와 의 최대 공약수 는 와 의 최대 공약수가 된다.
- 따라서 를 로 나눈 몫을 라고 하고, 나머지를 이라고 한다면 는 과 같다.
int gcd(int x, int y) { int r; while (y) { r = x % y; // (1), (4), (7) x = y; // (2), (5), (8) y = r; // (3), (6), (9) } return x; }
- 두 개의 정수 와 을 와 에 전달하고, 를 로 나눈 나머지를 이라고 할 때, 와 의 최대 공약수는 와 의 최대 공약수와 같으므로 먼저 를 로 나눈 나머지 을 구한 후, 같은 작업을 반복하기 위해서 의 값에 의 값을 대입하고 의 값에 의 값을 대입한다.
- 를 로 나눈 나머지가 일 때, 제수 가 최대 공약수가 되지만, 한 번 더 다음 과정을 진행하면 에 의해서 의 값은 의 값이 되고, 에 의해서 의 값은 이 되므로 최대 공약수인 의 값을 반환한다.

코드
#include <iostream> using namespace std; int gcd(int x, int y) { int r; while (r) { r = x % y; x = y; y = r; } return x; } int main() { int a, b; cin >> a >> b; cout << gcd(a, b) << '\n'; return 0; }
12 18 6
최소 공배수(LCM; Least Common Multiple)
- 두 개 이상의 자연수들의 공통인 배수들의 모임을 공배수(Common Multiple)라고 하고, 공배수 중에서 가장 작은 수를 최소 공배수(Least Common Multiple)라고 한다.
- 예) 의 배수는 이고 의 배수는 일 때, 두 수 과 의 공배수는 이고 최소 공배수는 가 된다.

- 두 개의 자연수 와 의 최대 공약수를 라고 하고 최소 공배수를 이라고 하면 다음과 같은 관계식이 성립한다.
- 와 의 최대 공약수가 이므로 ( 는 서로소)로 나타낼 수 있다.
- 그러면 두 수의 최소 공배수()는 가 된다.
- 두 수 와 를 곱하면 가 되고, 최대 공약수()와 최소 공배수()를 곱하면 는 가 된다.
- 두 수 와 의 곱은 최소 공배수인 과 최대 공약수인 를 곱한 값과 같기 때문에 최소 공배수는 알고리즘을 따로 작성하여 구하는 것이 아니라, 두 수 와 를 곱한 후 최대 공약수 로 나누면 구할 수 있다.
코드
#include <iostream> using namespace std; int gcd(int x, int y) { int r; while (r) { r = x % y; x = y; y = r; } return x; } int main() { int a, b; cin >> a >> b; cout << a * b / gcd(a, b) << '\n'; return 0; }
3 4 12
재귀 함수를 이용하여 최대 공약수/최소 공배수 구하기
- 최대 공약수와 최소 공배수를 다음과 같이 재귀 함수를 이용하여 구할 수 있다.
// GCD : 최대공약수 int gcd(int x, int y) { if (x == 0) return y; else return gcd(y % x, x); } // LCM : 최소공배수 int lcm(int x, int y) { return (x * y) / gcd(x, y); }
참고 사이트
유클리드 호제법 - 위키백과, 우리 모두의 백과사전
위키백과, 우리 모두의 백과사전. 유클리드 호제법(-互除法, Euclidean algorithm) 또는 유클리드 알고리즘은 2개의 자연수 또는 정식(整式)의 최대공약수를 구하는 알고리즘의 하나이다. 호제법이란
ko.wikipedia.org
최소공배수 - 나무위키
예시로 두 수 10, 12의 공배수를 찾고 싶다고 하자. 먼저 두 수의 배수를 쭉 나열한다. 10: 10, 20, 30, 40, 50, 60, 70, ... 12: 12, 24, 36, 48, 60, 72, ... 여기서 위아랫줄 동시에 나타나는 수가 바로 공배수이다.
namu.wiki
최대공약수 - 나무위키
예시로 두 수 12, 18의 공약수 및 최대공약수를 찾고 싶다고 하자. 간단하게, 두 수의 약수를 모두 나열한다. 12: 1, 2, 3, 4, 6, 12 18: 1, 2, 3, 6, 9, 18 여기서 위아랫줄 모두 같이 있는 숫자가 공약수가 된
namu.wiki
728x90
728x90
'Computer Science > 알고리즘' 카테고리의 다른 글
[Algorithm] 백트래킹(Backtracking) (0) | 2022.11.16 |
---|---|
[Algorithm] 이항 계수(Binomial Coefficient) (0) | 2022.11.15 |
[Algorithm] 브루트 포스(Brute Force) (0) | 2022.11.03 |
[Algorithm] 하노이 탑(Tower of Hanoi) (0) | 2022.11.03 |
[Algorithm] 스캐닝 메소드(Scanning Method) (0) | 2022.10.26 |
[Algorithm] 부분합(Partial Sum) ; 누적합(Prefix Sum) (0) | 2022.10.26 |
[Algorithm] 형상수(Figulate Number) (0) | 2022.10.26 |
[Algorithm] 에라토스테네스의 체(Sieve of Erathosthenes) (0) | 2022.10.25 |