백준/C++

[백준] 2609번: 최대공약수와 최소공배수 | C++ 풀이

성실한 당근농부 2023. 7. 5. 23:41

# 문제

두 개의 자연수를 입력받아 최대 공약수와 최소 공배수를 출력하는 프로그램을 작성하시오.

 

 


 

# 풀이

유클리드 호제법을 이용해 푸는 문제다.

1. 두 수 중에서 큰 수를 a, 작은 수를 b라고 하고 a를 b로 나눈다.
2. a가 b로 나누어떨어지면 두 수의 최대공약수는 b이다.
3. a가 b로 나누어떨어지지 않으면 a를 b로 나눈 나머지와 b에 대하여 1번부터 다시 반복한다.

출처: 생활코딩 C언어의 기초 문법

 

 

그림으로 다시 한번 확인해보자.

246과 183의 최대공약수를 구하고자 한다. 더 큰 수인 246을 a로 놓고 183을 b로 놓은 후 a%b로 나머지 연산을 한다.

나머지(r)가 0이 아니므로 b를 a로, 나머지(r)를 b로 놓고 다시 나머지 연산을 수행한다.

나머지가 0일때까지 해당 연산을 반복하고, 나머지가 0이 될 때의 b가 두 수의 최대공약수이다.

 

 

 


 

 

그럼 정답 소스코드를 바로 확인해보자.

 

#include <iostream>
using namespace std;

int gcd(int a, int b);

int main(){
    int a, b, r;
    cin >> a >> b;

    int GCD = gcd(a, b);
    int LCM = a*b / GCD;

    cout << GCD << '\n' << LCM;
    return 0;
}

int gcd(int a, int b){
    int r = a%b;
    while(r != 0){
        a = b;
        b = r;
        r = a%b;
    }
    return b;
}

최대공약수를 구하는 과정에서는 반복문을 사용해도 되고, 재귀를 사용해도 된다.

재귀를 사용한 코드는 마지막에 풀이 없이 코드만 올려두도록 하겠다.

위에서 설명한 유클리드 호제법 알고리즘을 최대공약수를 구하는 함수인 gcd 안에 구현해주면 된다.

최대공약수를 구하고 나면 최소공배수는 쉽게 구할 수 있다.

입력된 두 수의 곱과 최대공약수, 최소공배수의 곱이 같다는 걸 이용해 최소공배수까지 구해주면 출력만 하면 끝이다.

 

 

재귀를 사용한 코드는 아래와 같고, 입력이 크지 않아서 그런지 메모리와 시간 소요는 동일했다.

#include <iostream>
using namespace std;

int gcd(int a, int b);

int main(){
    int a, b, r;
    cin >> a >> b;

    int GCD = gcd(a, b);
    int LCM = a*b / GCD;

    cout << GCD << '\n' << LCM;
    return 0;
}

int gcd(int a, int b){
    if(b == 0) 
        return a; // a와 b를 사용해 r을 따로 만들지 않았음에 주의!
        
    return gcd(b, a%b);
}

 

 

 

 

 

 


 

 

 

2609번: 최대공약수와 최소공배수

첫째 줄에는 입력으로 주어진 두 수의 최대공약수를, 둘째 줄에는 입력으로 주어진 두 수의 최소 공배수를 출력한다.

www.acmicpc.net

 

728x90