문제
자세한 문제 내용은 ‘최소공배수‘를 클릭하세요.
풀이
이번 문제는 주어진 두 자연수 A, B의 최소공배수를 구하는 문제입니다. 최소공배수는 최대공약수를 통해 구할 수 있는데, 그 공식은 다음과 같습니다.
최소공배수(LCM) = (첫 번째 수 × 두 번째 수) / 최대공약수(GCD)
최소공배수는 두 수를 곱한 값에 최대공약수를 나눈 결과입니다. 이 공식은 두 수가 서로소(공약수가 1인 경우)인 경우에도 사용될 수 있습니다.
이 문제를 풀기위해서는 최대공약수를 구하는 알고리즘을 알아야 합니다. 최대공약수를 구하는 알고리즘은 여러가지가 있지만, 여기서는 유클리드 호제법을 이용해 문제를 풀어보기로 했습니다.
유클리드 호제법(Euclidean algorithm) : 최대공약수를 구하는 간결한 알고리즘
숫자 이론에서 최대공약수(GCD, Greatest Common Divisor)는 두 개 이상의 숫자의 공통된 약수 중 가장 큰 수를 의미합니다. 유클리드 호제법은 오래된 알고리즘으로, 두 숫자의 최대공약수를 효과적으로 찾는 방법을 제공합니다. 이 알고리즘은 매우 간결하며 효율적이어서 널리 사용되고 있습니다.
유클리드 호제법은 두 개의 숫자를 가지고 작업하며, 각 단계에서 나머지 연산을 사용합니다. 두 숫자를 A와 B라고 가정해봅시다. A를 B로 나눈 나머지를 R이라고 합시다. 이때, A와 B의 최대공약수는 B와 R의 최대공약수와 같습니다. 이 아이디어를 재귀적으로 적용하여 최대공약수를 찾을 수 있습니다.
다음은 유클리드 호제법의 단계를 보여주는 간단한 예시입니다. 우리는 270과 192의 최대공약수를 구하려고 합니다.
- 270을 192로 나눕니다. 나머지는 78입니다.
- 192를 78로 나눕니다. 나머지는 36입니다.
- 78을 36으로 나눕니다. 나머지는 6입니다.
- 36을 6으로 나눕니다. 나머지는 0입니다.
- 나머지가 0이 되면, 이전 단계의 나누는 수가 최대공약수입니다. 따라서 270과 192의 최대공약수는 6입니다.
유클리드 호제법은 숫자의 크기에 관계없이 적용될 수 있으며, 계산 속도가 빠르기 때문에 널리 사용됩니다. 또한, 이 알고리즘은 다른 숫자 이론 문제에도 응용될 수 있습니다. 예를 들어, 최소공배수(LCM, Least Common Multiple)를 구하는 문제에도 사용될 수 있습니다.
테스트 코드
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
import io.kotest.core.spec.style.StringSpec import io.kotest.matchers.shouldBe import java.io.BufferedReader import java.io.StringReader class No1934Test : StringSpec({ "최소공배수 : https://www.acmicpc.net/problem/1934" { val testCases = listOf( "3\n1 45000\n6 10\n13 17" to "45000\n30\n221" ) testCases.forEach { (given, expected) -> val actual = No1934.solve(BufferedReader(StringReader(given))) actual shouldBe expected } } }) |
프로덕션 코드
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 31 32 |
import java.io.BufferedReader fun main() { val input = System.`in`.bufferedReader() val output = System.out.bufferedWriter() output.write(No1934.solve(input)) input.close() output.flush() output.close() } object No1934 { fun solve(input: BufferedReader): String { val n = input.readLine().toInt() val results = mutableListOf<Int>() repeat(n) { val (a, b) = input.readLine().split(" ").map { it.toInt() } val d = gcd(a, b) results.add(a * b / d) } return results.joinToString("\n") } private fun gcd(a: Int, b: Int): Int { return if (b == 0) a else gcd(b, a % b) } } |
결과

실행 결과