https://www.acmicpc.net/problem/2608
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))
'알고리즘 > 백준 문제 풀이' 카테고리의 다른 글
[Python] 10166번 관중석 (0) | 2024.03.07 |
---|---|
[Python] 13705번 Ax+Bsin(x)=C (0) | 2024.02.28 |
[Python] 11037번 중복 없는 수 (0) | 2024.02.28 |
[Python] 12445번 バクテリアの増殖 (Small) (0) | 2024.02.27 |
[Python] 27114번 조교의 맹연습 (0) | 2024.02.27 |