2608번: 로마 숫자백준/문제2024. 3. 20. 12:46
Table of Contents
문제 출처 : https://www.acmicpc.net/problem/2608
언어 : Kotlin
문제 설명 :
로마 시대 때는 현재 사용하는 아라비아 숫자가 아닌 다른 방법으로 수를 표현하였다.
로마 숫자는 다음과 같은 7개의 기호로 이루어진다.
기호 | I | V | X | L | C | D | M |
값 | 1 | 5 | 10 | 50 | 100 | 500 | 1000 |
수를 만드는 규칙은 다음과 같다.
- 보통 큰 숫자를 왼쪽에 작은 숫자를 오른쪽에 쓴다. 그리고 그 값은 모든 숫자의 값을 더한 값이 된다. 예를 들어 LX = 50 + 10 = 60 이 되고, MLI = 1000 + 50 + 1 = 1051 이 된다.
V, L, D는 한 번만 사용할 수 있고 I, X, C, M은 연속해서 세 번까지만 사용할 수 있다. 예를 들어 VV나 LXIIII 와 같은 수는 없다. 그리고 같은 숫자가 반복되면 그 값은 모든 숫자의 값을 더한 값이 된다. 예를 들어 XXX = 10 + 10 + 10 = 30 이 되고, CCLIII = 100 + 100 + 50 + 1 + 1 + 1 = 253 이 된다. - 작은 숫자가 큰 숫자의 왼쪽에 오는 경우는 다음과 같다. IV = 4, IX = 9, XL = 40, XC = 90, CD = 400, CM = 900 을 나타낸다. 이들 각각은 한 번씩만 사용할 수 있다. 그런데 IV 와 IX 는 같이 쓸 수 없으며 XL 과 XC, CD 와 CM 또한 같이 쓸 수 없다. 이들 외에는 작은 숫자가 큰 숫자 왼쪽 어디에도 나올 수 없다. 예를 들어 XCXC 나 CMCD, VX 나 IIX 와 같은 수는 없다. 참고로 LIX = 50 + 9 = 59, CXC = 100 + 90 = 190 이 된다.
- 모든 수는 가능한 가장 적은 개수의 로마 숫자들로 표현해야 한다. 예를 들어 60 은 LX 이지 XLXX 가 아니고, 5 는 V 이지 IVI 가 아니다.
아래의 예를 참고 하시오.
- DLIII = 500 + 50 + 3 = 553
- MCMXL = 1000 + 900 + 40 = 1940
- 235 = CCXXXV
- 2493 = MMCDXCIII
로마 숫자로 이루어진 두 수를 입력받아 그 둘을 더한 값을 아라비아 숫자와 로마 숫자로 출력하는 프로그램을 작성하시오.
입력 :
첫째 줄과 둘째 줄에 하나씩 로마 숫자로 표현된 수가 주어진다. 입력된 각 수는 2000 보다 작거나 같고, 두 수의 합은 4000보다 작다.
출력 :
입력으로 주어진 두 수를 더한 값을 첫째 줄에 아라비아숫자로 출력하고 둘째 줄에는 로마 숫자로 출력한다.
제한 사항 :
- 시간 제한 : 1초
- 메모리 제한 : 128MB
입출력 예 :
입력 | 출력 |
DLIII MCMXL |
2493 MMCDXCIII |
풀이 :
숫자로 변환하는건 간단하지만 문자열로 변환하는게 길어졌다.
이보다 더 나은 방법이 있으리라 생각한다.
++ 다른사람의 풀이를 보니 키에 문자를 넣고 값에 해당하는 수를 넣어 깔끔하게 표현했다.
++ HashMap과 TreeMap을 사용했다.
++ 그렇게 풀어진 코드의 길이는 86줄로 현재 149줄인 필자의 코드에 비하면 훨씬 간결하다.
++ 해당 코드가 BufferedReader-Writer를 안썼다는 것을 감안하여 149 - 9을 한다쳐도 140과 86줄의 차이는 크다.
import java.io.BufferedReader
import java.io.BufferedWriter
import java.io.InputStreamReader
import java.io.OutputStreamWriter
fun main() = with(BufferedReader(InputStreamReader(System.`in`))) {
val bw = BufferedWriter(OutputStreamWriter(System.out))
val a = readLine()
val b = readLine()
val sum = numMaker(a) + numMaker(b)
val rome = strMaker(sum)
bw.write("$sum\n$rome")
bw.flush()
bw.close()
}
fun strMaker(n: Int): String {
var temp = n
val sb = StringBuilder()
val vld = BooleanArray(3) { false } // V, I, D
val ixcm = IntArray(4) { 0 } // I, X, C, M
val checker = BooleanArray(3) { false } // (IV, IX), (XL, XC), (CD, CM)
repeater@ while (true) {
if (temp >= 1000 && ixcm[3] <= 3) {
temp -= 1000
ixcm[3]++
sb.append("M")
continue@repeater
}
if (temp >= 900) {
temp -= 900
checker[2] = true
sb.append("CM")
}
if (temp >= 500 && !vld[2]) {
temp -= 500
vld[2] = true
sb.append("D")
}
if (temp >= 400 && !checker[2]) {
temp -= 400
checker[2] = true
sb.append("CD")
}
if (temp >= 100 && ixcm[2] <= 3) {
temp -= 100
ixcm[2]++
sb.append("C")
continue@repeater
}
if (temp >= 90) {
temp -= 90
checker[1] = true
sb.append("XC")
}
if (temp >= 50 && !vld[1]) {
temp -= 50
vld[1] = true
sb.append("L")
}
if (temp >= 40 && !checker[1]) {
temp -= 40
checker[1] = true
sb.append("XL")
}
if (temp >= 10 && ixcm[1] <= 3) {
temp -= 10
ixcm[1]++
sb.append("X")
continue@repeater
}
if (temp >= 9) {
temp -= 9
checker[0] = true
sb.append("IX")
}
if (temp >= 5 && !vld[0]) {
temp -= 5
vld[0] = true
sb.append("V")
}
if (temp >= 4 && !checker[0]) {
temp -= 4
checker[0] = true
sb.append("IV")
}
if (temp >= 1 && ixcm[0] <= 3) {
temp -= 1
ixcm[0]++
sb.append("I")
continue@repeater
}
if (temp == 0) break@repeater
}
return sb.toString()
}
fun numMaker(n: String): Int {
val list = mutableListOf<Int>()
var idx = 0
while (idx < n.length) {
if (idx + 1 < n.length) {
when ("${n[idx]}${n[idx + 1]}") {
"IV" -> { list += 4; idx++ }
"IX" -> { list += 9; idx++ }
"XL" -> { list += 40; idx++ }
"XC" -> { list += 90; idx++ }
"CD" -> { list += 400; idx++ }
"CM" -> { list += 900; idx++ }
else -> list += toNum(n[idx].toString())
}
} else {
list += toNum(n[idx].toString())
}
idx++
}
return list.sum()
}
fun toNum(n: String): Int {
return when (n) {
"I" -> 1
"V" -> 5
"X" -> 10
"L" -> 50
"C" -> 100
"D" -> 500
"M" -> 1000
else -> -99999
}
}
'백준 > 문제' 카테고리의 다른 글
11536번: 줄 세우기 (0) | 2024.03.21 |
---|---|
20365번: 블로그2 (0) | 2024.03.20 |
5656번: 비교 연산자 (0) | 2024.03.20 |
11179번: 2진수 뒤집기 (2) | 2024.03.19 |
5026번: 박사 과정 (1) | 2024.03.19 |
@스몰스테핑 :: 작은 발걸음
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!