문제
자세한 문제 내용은 ‘분수찾기‘를 클릭하세요.
풀이
주어진 문제는 무한히 큰 배열에 나열된 분수들 중에서 주어진 순서(X번째)에 해당하는 분수를 찾는 문제입니다. 주어진 순서에 따라 분수들이 지그재그 순서로 나열되어 있습니다.
문제를 해결하기 위해서는 각 분수의 위치와 값 사이의 규칙을 이해하는 것이 중요합니다. 이 문제에서는 다음과 같은 규칙을 발견할 수 있습니다:
- 분수의 위치(row, column)를 기준으로 다음과 같이 값(numerator, denominator)을 구할 수 있습니다:
- 분자(numerator) = row – (column – 1)
- 분모(denominator) = column
- 분수의 위치(row, column)을 기준으로 해당 위치까지의 분수 개수(total)를 구할 수 있습니다:
- total = (row + column – 1) * (row + column) / 2
따라서, 주어진 순서 X에 해당하는 분수를 찾기 위해 다음과 같은 절차를 수행할 수 있습니다:
- 분수의 위치(row, column)를 찾기 위해, X에 해당하는 분수 개수(total)를 구합니다. 이를 위해 total 변수를 1부터 증가시키며 X보다 작거나 같은 total 값을 찾습니다.
- X와 total의 차이를 구하여 delta 변수에 저장합니다. (delta = X – total)
- delta가 홀수인 경우, 분수의 위치는 (delta + 1, column – delta)입니다. 분수의 값은 위에서 언급한 규칙에 따라 계산합니다.
- delta가 짝수인 경우, 분수의 위치는 (column – delta, delta + 1)입니다. 분수의 값은 위에서 언급한 규칙에 따라 계산합니다.
위의 절차를 따라 구현하면 주어진 순서 X에 해당하는 분수를 찾을 수 있습니다.
테스트 코드
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 |
package boj.problems.step8 import io.kotest.core.spec.style.StringSpec import io.kotest.matchers.shouldBe class No1193Test : StringSpec({ "분수찾기 : https://www.acmicpc.net/problem/1193" { val testCases = listOf( 1 to "1/1", 2 to "1/2", 3 to "2/1", 4 to "3/1", 5 to "2/2", 6 to "1/3", 7 to "1/4", 8 to "2/3", 9 to "3/2", 14 to "2/4" ) testCases.forEach { (input, output) -> val actual = No1193.solve(input) actual shouldBe output } } }) |
프로덕션 코드
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 |
package boj.problems.step8 fun main() { val input = System.`in`.bufferedReader() val output = System.out.bufferedWriter() output.write(No1193.solve(input.readLine().toInt())) input.close() output.flush() output.close() } object No1193 { fun solve(input: Int): String { var crossCount = 1 var prevCountSum = 0 while (true) { if (input <= prevCountSum + crossCount) { if (crossCount % 2 == 1) { return (crossCount - (input - prevCountSum - 1)).toString() + "/" + (input - prevCountSum) } return (input - prevCountSum).toString() + "/" + (crossCount - (input - prevCountSum - 1)) } prevCountSum += crossCount crossCount++ } } } |
결과

실행 결과