ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [백준 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


    댓글

Designed by Tistory.