본문 바로가기
Algorithm/Java

Baekjoon Online Judge _ 01934 _ 최소공배수

by autumnly 2016. 12. 28.

[ Baekjoon Online Judge _ 01934 _ 최소공배수 ]



문제

두 자연수 A와 B에 대해서, A의 배수이면서 B의 배수인 자연수를 A와 B의 공배수라고 한다. 이런 공배수 중에서 가장 작은 수를 최소공배수라고 한다. 예를 들어, 6과 15의 공배수는 30, 60, 90등이 있으며, 최소 공배수는 30이다.

두 자연수 A와 B가 주어졌을 때, A와 B의 최소공배수를 구하는 프로그램을 작성하시오.

입력

첫째 줄에 테스트 케이스의 개수 T(1 ≤ T ≤ 1,000)가 주어진다. 둘째 줄부터 T개의 줄에 걸쳐서 A와 B가 주어진다. (1 ≤ A, B ≤ 45,000)

출력

첫째 줄부터 T개의 줄에 A와 B의 최소공배수를 입력받은 순서대로 한 줄에 하나씩 출력한다.

예제 입력

3
1 45000
6 10
13 17

예제 출력

45000
30
221




풀이

최소공배수는 두 수를 곱한 뒤 최대공약수로 나누면 된다는 아이디어로 풀었다.

최대공약수를 구할 때는 for문으로 일일히 나눠보는 방법을 택했는데,


다른 알고리즘 찾아보다 유클리드 호제법 을 알게됐다.

유클리드 호제법을 사용하면 좀 더 빠른 시간 내에 최대공약수를 찾을 수 있다.


유클리드 호제법이란

자연수 a, b에 대해서 a를 b로 나눈 나머지를 r이라 하면(단, a>b), a와 b의 최대공약수는 b와 r의 최대공약수와 같다.

는 성질을 이용한 알고리즘이다.

1
2
3
4
5
 public static int gcd(int p, int q)
 {
    if (q == 0return p;
    return gcd(q, p%q);
 }
cs

이렇게 재귀적으로 짜면 훨씬 간단하고 빠른 연산이 가능하다.

밑의 코드는 내가 처음에 짰던 코드이다.



코드

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);
        int T, A, B, LCM, i;
        int GCD = 1//최대공약수
        
        T = sc.nextInt();
        
        while(T-- > 0){
            A = sc.nextInt();
            B = sc.nextInt();
            
            //A, B를 동시에 나누어 떨어지게 하는 수중 가장 큰 수를 찾는다 (== 최대공약수)
            for(i = Math.min(A,B); !(A%i == 0 && B%i == 0 && i > 0); i-- );
            GCD = i;
            //A와 B를 곱한 뒤 최대공약수로 나눠주면 최소공배수가 된다
            LCM = (A * B) / GCD;
            System.out.println(LCM);
        }//end while
    }
}
 
cs