안녕하세요. 회사와 함께 성장하고 싶은 KOSE입니다.
이번 포스팅은 백준 문자열 문제 - 디지털시계 코틀린 풀이를 진행하고자 합니다.
문제 출처: https://www.acmicpc.net/problem/1942
1. 풀이 소스
import java.io.*
const val LAST_TIME_SECONDS_OF_DAY: Int = 3600 * 23 + 59 * 60 + 59
const val START_TIME_SECONDS_OF_DAY: Int = 0
fun main() = BufferedReader(InputStreamReader(System.`in`)).use {
val sb = StringBuilder()
repeat(3) {
val (startTimeSeconds, endTimeSeconds) = readlnOrNull()!!.split(" ").map { it.toTimeSeconds() }
val result = when {
startTimeSeconds <= endTimeSeconds -> calculateMultipleOfThreeBetween(startTimeSeconds, endTimeSeconds)
else -> calculateMultipleOfThreeBetween(startTimeSeconds, LAST_TIME_SECONDS_OF_DAY) +
calculateMultipleOfThreeBetween(START_TIME_SECONDS_OF_DAY, endTimeSeconds)
}
sb.append(result).append("\n")
}
println(sb)
}
private fun calculateMultipleOfThreeBetween(startTimeSeconds: Int, endTimeSeconds: Int): Int {
var targetTimeSeconds = startTimeSeconds
var result = 0
while (targetTimeSeconds <= endTimeSeconds) {
val longOfTime = targetTimeSeconds.transformTimeToLiteralNumber()
if (longOfTime % 3 == 0) {
result++
}
if (targetTimeSeconds == LAST_TIME_SECONDS_OF_DAY) {
break
}
targetTimeSeconds++
}
return result
}
fun Int.transformTimeToLiteralNumber(): Int {
val hours = this / 3600
val minutes = (this % 3600) / 60
val seconds = this % 60
return hours * 10000 + minutes * 100 + seconds
}
fun String.toTimeSeconds(): Int {
val (hours, minutes, seconds) = this.split(":").map { it.toInt() }
return hours * 3600 + minutes * 60 + seconds
}
2. 풀이 중점사항
- 시작 시간과 종료 시간의 대수 비교
시작 시간이 종료 시간보다 클 경우 (ex: 23:59:59, 00:00:01) 시작 시간 ~ 23:59:59, 00:00:00 ~ 종료 시간 으로 구획을 나눠서 진행해야합니다.
만약, 시작 시간보다 종료 시간이 클 경우는 시작 시간 <= 종료 시간이 될 때 까지 순회하면 됩니다.
val result = when {
startTimeSeconds <= endTimeSeconds -> calculateMultipleOfThreeBetween(startTimeSeconds, endTimeSeconds)
else -> calculateMultipleOfThreeBetween(startTimeSeconds, LAST_TIME_SECONDS_OF_DAY) +
calculateMultipleOfThreeBetween(START_TIME_SECONDS_OF_DAY, endTimeSeconds)
}
-시작 시간과 종료 시간 사이의 범위구하기
시작 시간과 종료 시간은 초(단위)로 바꿔서 구할 수 있습니다.
예를 들어 00:00:00 ~ 00:01:03이 있다면 이를 초(단위)로 표현하면 0 ~ 63이 됩니다.
fun String.toTimeSeconds(): Int {
val (hours, minutes, seconds) = this.split(":").map { it.toInt() }
return hours * 3600 + minutes * 60 + seconds
}
0 ~ 63까지 순회하되, 순회한 숫자를 시간 문자 그대로의 숫자로 바꿔주어야 합니다.
0 -> 00:00:00 -> 0
63 -> 00:01:03 -> 103
이를 위해 시간, 분, 초로 바꾼 후 각 단위에 맞게 10의 제곱승을 곱해줄 수 있습니다.
fun Int.transformTimeToLiteralNumber(): Int {
val hours = this / 3600
val minutes = (this % 3600) / 60
val seconds = this % 60
return hours * 10000 + minutes * 100 + seconds
}
이렇게 구한 문자 그대로의 시간을 표현하는 정수를 3의 배수인지 파악하고 결과를 리턴하면 결과를 얻을 수 있습니다!
private fun calculateMultipleOfThreeBetween(startTimeSeconds: Int, endTimeSeconds: Int): Int {
var targetTimeSeconds = startTimeSeconds
var result = 0
while (targetTimeSeconds <= endTimeSeconds) {
val longOfTime = targetTimeSeconds.transformTimeToLiteralNumber()
if (longOfTime % 3 == 0) {
result++
}
if (targetTimeSeconds == LAST_TIME_SECONDS_OF_DAY) {
break
}
targetTimeSeconds++
}
return result
}
이상으로 백준 디지털시계 문제 풀이를 마치도록 하겠습니다. 감사합니다!
'Algorithm' 카테고리의 다른 글
[Algorithm] 백준 문자열 문제 - 경고(3029) 코틀린 풀이 (0) | 2023.09.07 |
---|---|
[Algorithm] 백준 MST 문제 - 별자리 만들기(4386) 자바 풀이 (0) | 2023.05.24 |
[Algorithm] 백준 LIS 문제 - 가장 긴 증가하는 부분 수열 5(14003) 자바 풀이 (0) | 2023.05.24 |
[Algorithm] 백준 LCS 문제 - LCS 2(9252) 자바 풀이 (0) | 2023.05.24 |
[Algorithm] 백준 이분탐색 문제 - 공유기 설치(2110) 자바 풀이 (0) | 2023.05.24 |