알고리즘/수학

[백준 2609] - [수학 최소공배수 최대공약수] - 최대공약수와 최소공배수(JAVA)

팡스 2018. 12. 3. 15:35

문제 링크 : https://www.acmicpc.net/problem/2609




이문제는 입력 받는 두 수의 최대 공약수와 최소 공배수를 구하는 문제이다. 


최대 공약수는 두 개 이상의 수가 공통으로 가지는 약수 중 가장 큰 수를 말한다.


두 수 18과 24가 있다 하면 각각의 약수는 다음과 같다.

18의 약수 : 1, 2, 3, 6, 9, 18

24의 약수 : 1, 2, 3, 4, 6, 8, 12, 24

이들 약수중에 공통으로 가지는 약수는 {1, 2, 3, 6}이고 이들 중 가장 큰 수는 6이 된다. 


먼저 18의 약수를 구하고 24의 약수를 구한다음 각 각 의 약수중에서 공통 약수를 추려낸 뒤 그중 제일 큰 수를 찾았다.


수의 크기가 작은 경우 빠르게 구할 수 있겠지만 만약 수가 큰 수라면 어떻게 될까?

각각 약수를 구한뒤 공약수를 구하고 최대 공약수를  구하는 과정은 굉장히 비효율적으로 보인다.


그럼 두 수의 최대공약수를 가장 효율적으로 구할 수 있는 방법이 무엇이 있을까?

유클리드 호제법을 통해서 두 수의 최대 공약수를 빠르게 구할 수 있다.


유클리드 호제 법으로 최대공약수 구하는 방식


여기서 기억할 공식은 큰 수 A를 작은수 B로 나누었을때 나누어 떨어진다면 최대공약수는 B가 된다.


1)  입력 받은 두 수중 큰 수를 A, 작은수를 B로 정한다.

2)  A 를 B 로 나눈값의 나머지를 R로 지칭한다.

3)  R 이 0이라면 A는 B로 나누어 지기 때문에 최대 공약수는 B가 된다.

4)  만약 R이 0이 아니라면 A값은 B로, B 값은 R로 변경한뒤 3번 과정을 반복한다. 


위의 유클리드 호제법을 자바 소스로 보면 다음과 같다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import java.util.Scanner;
 
public class Main {
 
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        
        long num1 = sc.nextLong();
        long num2 = sc.nextLong();
 
        // 큰수를 앞에 작은 수를 뒤에 위치시킨다.
        long gcd = getGCD(Math.max(num1, num2), Math.min(num1, num2));
        
        System.out.println(gcd);
    }
 
    public static long getGCD(long a, long b) {
        while(b > 0) {
            long tmp = a;
            a = b;
            b = tmp%b;
        }
        return a;
    }
}
cs



최대 공약수를 구했으니 이제 최소 공배수를 알아보자.


최소공배수는 두개 이상의 수가 공통으로 가지는 배수 중 가장 작은 수를 말한다.


두 수 18과 24가 존재 할때 두 수의 배수는 다음과 같이 진행된다.


18의 배수 18, 36, 54, 72, 90 ...

24의 배수 24, 48, 72, 96 ...


두 수의 배수에서 같은 배수는 72로 나온다. 


최소 공배수를 구할때 두 수 A, B의 배수를 각각  구해가면서  A의 n번째 배수와 B의 m 번째 배수가 같으면 그 수가 최소 공배수가 되는 것이다.


하지만 1과 100000 의 최악의 예제를 받았을 경우


1의 배수를 100000 까지 구해야 최소공배수 100000을 구할 수 있다. 


이또한 굉장히 비효율 적인 방식이다.


최소 공배수를 구하는 가장 효율적인 방법은 위의 최대공약수를 구할때 사용한 유클리드 호제법을 이용하여 풀면 된다.


1) 두 수의 최대 공약수를 유클리드 호제법을 통하여 구한다.

2) 두 수 A, B를 곱한뒤 최대 공약수로 나눈 값을 최소 공배수로 출력한다.


위의 방법으로 최소 공배수를 구할 수 있다.


방금 정리한 최대 공약수와 최소 공배수를 구하는 방법으로 백준 2609 문제를 풀면 된다.


소스

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import java.util.Scanner;
 
public class Main {
 
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        
        long num1 = sc.nextLong();
        long num2 = sc.nextLong();
        
        long gcd = getGCD(Math.max(num1, num2), Math.min(num1, num2));
        long lcm = getLCM(num1, num2, gcd);
        
        System.out.println(gcd);
        System.out.println(lcm);
    }
 
    public static long getGCD(long a, long b) {
        while(b > 0) {
            long tmp = a;
            a = b;
            b = tmp%b;
        }
        return a;
    }
    
    public static long getLCM(long a, long b, long gcd) {
        return (a*b)/gcd;
    }
}
cs