본문 바로가기

알고리즘/백준 문제 풀이

[Python] 2608번 로마 숫자

728x90

https://www.acmicpc.net/problem/2608

 

2608번: 로마 숫자

첫째 줄과 둘째 줄에 하나씩 로마 숫자로 표현된 수가 주어진다. 입력된 각 수는 2000 보다 작거나 같고, 두 수의 합은 4000보다 작다.

www.acmicpc.net


 

24/02/27

 

 

단순한 구현 + 문자열 문제이다. 사소한 실수로 두 번 정도 틀렸습니다를 받았다.


 

문제 접근 방식:

 

 

문제에서 요구하고자 하는 것은 로마 숫자로 주어진 두 수를 더하고, 그 결과를 하나는 아라비아 숫자로, 하나는 로마 숫자로 출력하는 것이다.

 

문제를 읽던 도중 생각난 방법은 아라비아 숫자와 로마 숫자 사이의 일대일 대응 표를 만들어서 각 자리 숫자 별로 매칭을 시키면 충분할 것이라는 방법이었다.

 

마침 문제 제한을 보았고, 두 수가 모두 $2,000$보다 작거나 같은 수가 주어지고, 두 수의 합이 $4,000$보다 작음이 보장됨을 확인했다.

 

따라서, 일의 자리, 십의 자리, 백의 자리, 천의 자리에 해당하는 아라비아 수 to 로마 수 대응 관계를 딕셔너리로 구현했다.

 

이를 이용하여 아라비아 숫자를 로마 숫자로 변형하는 함수 arabia_to_rome을 구현했다.

 

이 함수는 기존 아라비아 숫자를 $10$으로 나눠가며 해당되는 수 만큼의 로마 수를 계속 이어 붙이는 식으로 구현이 되어있다.

 

로마 숫자를 아라비아 숫자로 바꾸는 함수 rome_to_arabia는 아이디어 하나가 필요했다.

 

III와 II와 같이 여러 개의 중복된 문자가 붙어 있는 경우를 어떻게 해석할 것인가가 중요했다.

 

이는 최대한 읽을 수 있을 때까지 읽고, 더 이상 읽지 못한다면 거기까지를 하나의 덩어리로 본다는 아이디어가 들어가야 했다.

 

나는 이를 포인터 두 개를 활용해 구현했다.


아래는 내가 위의 접근 방식과 같이 작성한 파이썬 코드이다. 더보기를 누르면 확인할 수 있다.

더보기
# 2608번 로마 숫자
# 문자열, 구현
ara_rom = {0: '', 1: 'I', 2: 'II', 3: 'III', 4: 'IV', 5: 'V',
       6: 'VI', 7: 'VII', 8: 'VIII', 9: 'IX', 10: 'X',
       20: 'XX', 30: 'XXX', 40: 'XL', 50: 'L', 60: 'LX',
       70: 'LXX', 80: 'LXXX', 90: 'XC', 100: 'C', 200: 'CC',
       300: 'CCC', 400: 'CD', 500: 'D', 600: 'DC', 700: 'DCC',
       800: 'DCCC', 900: 'CM', 1000: 'M', 2000: 'MM', 3000: 'MMM'}
rom_ara = dict()
for num, rome in ara_rom.items():
    rom_ara[rome] = num

def arabia_to_rome(num):
    digit = 1
    rome = ''
    while num:
        rome = ara_rom[digit * (num % 10)] + rome
        num //= 10
        digit *= 10
    return rome
def rome_to_arabia(rome):
    start, end = 0, 1
    num = 0
    while start < len(rome):
        if rome[start:end] in rom_ara and end <= len(rome):
            end += 1
        else:
            num += rom_ara[rome[start:end-1]]
            start = end-1
    return num
rome1 = input()
rome2 = input()
ans = rome_to_arabia(rome1) + rome_to_arabia(rome2)
print(ans)
print(arabia_to_rome(ans))