안녕하세요! 오늘은 코딩테스트에 자주 출제되는 알고리즘 중 하나인 유클리드 호제법에 대해 살펴보려고 합니다. 이 글에서는 유클리드 호제법이 무엇인지 개념적으로 이해하고, 실제 문제를 통해 이를 해결하는 과정을 단계별로 살펴볼 것입니다.
유클리드 호제법이란?
유클리드 호제법(Euclidean algorithm)은 두 수의 최대공약수(GCD, Greatest Common Divisor)를 구하는 효율적인 알고리즘입니다. 고대 그리스의 수학자 유클리드가 처음 소개한 이 방법은 두 수의 유한한 연산으로 GCD를 구할 수 있다는 점에서 매우 유용합니다.
유클리드 호제법의 기본 아이디어는 다음과 같습니다:
- 두 수 a와 b가 있을 때, a를 b로 나눈 나머지를 r이라고 하자. 즉, a = bq + r (q는 몫, r은 나머지).
- 이제 GCD(a, b)는 GCD(b, r)과 같습니다. 즉, 나머지로 계속해서 GCD를 구할 수 있습니다.
- 이 과정을 반복하다 보면 r이 0이 될 때가 오고, 이때의 b가 GCD입니다.
문제 예제: 최대공약수 구하기
이제 유클리드 호제법을 사용하여 최대공약수를 구하는 문제를 해결해 보겠습니다.
문제 설명
두 자연수 A와 B가 주어질 때, 이 두 수의 최대공약수를 구하는 프로그램을 작성하시오.
입력
- 첫째 줄에 두 자연수 A와 B가 주어진다. (1 ≤ A, B ≤ 1,000,000)
출력
- 첫째 줄에 A와 B의 최대공약수를 출력한다.
예제
입력:
24 36
출력:
12
유클리드 호제법 구현
이제 C++로 위의 문제를 해결하기 위해 유클리드 호제법을 구현해 보겠습니다. 아래는 C++ 코드입니다.
#include <iostream>
using namespace std;
// 최대공약수 함수
int gcd(int a, int b) {
while (b != 0) {
int r = a % b; // 나머지 계산
a = b; // a에 b 대입
b = r; // b에 나머지 대입
}
return a; // 최대공약수 반환
}
int main() {
int A, B;
cout << "A와 B를 입력하세요: ";
cin >> A >> B; // A와 B 입력 받기
cout << "최대공약수는: " << gcd(A, B) << endl; // 최대공약수 출력
return 0;
}
코드 설명
위 코드의 구조는 다음과 같습니다:
#include <iostream>
: C++에서 기본 입출력 기능을 사용하기 위한 헤더 파일입니다.using namespace std;
: 표준 네임스페이스를 사용하기 위한 구문으로, std::를 생략할 수 있게 해줍니다.int gcd(int a, int b)
: 두 수 a와 b의 최대공약수를 구하는 함수입니다. 반복문을 통해 b가 0이 될 때까지 r(나머지)을 계산합니다.int main()
: 프로그램의 시작점이며, 사용자로부터 입력을 받아 최대공약수를 출력하는 역할을 합니다.
프로그램 실행 과정
프로그램을 컴파일하고 실행하면, 사용자로부터 두 자연수를 입력받습니다. 예를 들어, 24와 36을 입력한다면, 프로그램은 다음과 같이 진행됩니다:
- 처음 a = 24, b = 36 이므로 r = 24 % 36 = 24입니다.
- 이제 a = 36, b = 24로 바뀝니다. 다시 r = 36 % 24 = 12입니다.
- 다시 a = 24, b = 12로 바뀌며 r = 24 % 12 = 0입니다.
- b가 0이 되었으므로 a의 값인 12가 최대공약수로 출력됩니다.
유클리드 호제법의 시간 복잡도
유클리드 호제법의 시간 복잡도는 O(log(min(a, b)))입니다. 이는 두 수의 크기가 비슷할 때, 적어도 매번 한 수가 반으로 줄어들기 때문에 매우 효율적이란 장점이 있습니다.
변형 문제
이제 유클리드 호제법을 변형하여 다른 문제를 해결해 볼 수 있습니다. 예를 들어, 두 수의 최소공배수(LCM)를 구하는 문제를 생각해 보겠습니다. 최소공배수는 다음과 같은 공식을 통해 구할 수 있습니다:
LCM(a, b) = (a * b) / GCD(a, b)
이 공식을 C++로 구현하면 다음과 같습니다:
#include <iostream>
using namespace std;
// 최대공약수 함수
int gcd(int a, int b) {
while (b != 0) {
int r = a % b;
a = b;
b = r;
}
return a;
}
// 최소공배수 함수
int lcm(int a, int b) {
return (a * b) / gcd(a, b); // LCM 계산
}
int main() {
int A, B;
cout << "A와 B를 입력하세요: ";
cin >> A >> B; // A와 B 입력 받기
cout << "최소공배수는: " << lcm(A, B) << endl; // LCM 출력
return 0;
}
결론
이번 글에서는 유클리드 호제법을 통해 최대공약수 및 최소공배수를 구하는 방법에 대해 알아보았습니다. 이 알고리즘은 효율적이고 간단한 방법으로, 다양한 문제 해결에 활용할 수 있습니다. 코딩 테스트에서 종종 출제되므로, 이를 연습하고 익혀두는 것이 중요합니다. 향후 더 많은 문제와 알고리즘을 다룰 예정이니 많은 관심 부탁드립니다! 감사합니다.