M28700: 罗马数字与整数的转换
implementation, dict, greedy, http://cs101.openjudge.cn/pctbook/M28700/
罗马数字包含以下七种字符:I、V、X、L、C、D和M。 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000 例如, 整数2写做II,即为两个并列的I。12写做XII,即为X+II。 27写做XXVII, 即为 XX+V+II。
通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如4不写做IIII,而是IV。I在V的左边,所表示的数等于大数5减小数1得到的数值4。同样地,数字9表示为IX。这个特殊的规则只适用于以下六种情况: I 可以放在 V (5) 和 X (10) 的左边,来表示4和9。 X 可以放在 L (50) 和 C (100) 的左边,来表示40和90。 C 可以放在 D (500) 和 M (1000) 的左边,来表示400和900。
题目要求:实现罗马数字和整数的转换。 1)如果输入是一个罗马数字,将其转换成整数; 2)如果输入是一个整数,将其转换为罗马数字。 无论是何种输入,整数在1到3999的范围内。
输入输出示例:
输入:III
输出:3
输入:4
输出:IV
输入:IX
输出:9
输入:58
输出:LVIII
输入:MCMXCIV
输出:1994
(M = 1000, CM = 900, XC = 90, IV = 4)
输入
一行字符(可能是罗马数字,也可能是正整数)
输出
如果输入是罗马数字,输出是正整数; 如果输入是正整数,输出是罗马数字。
样例输入
MCMXCIV样例输出
1994提示
tags: implementation 整数是正整数,数值范围1~3999。罗马数字中的字符是大写的。 可采用第一个字符判断输入是整数(0 ~ 9)还是罗马数字(不是0 ~ 9)。
思路:整数->罗⻢数字的过程中,利用字典的顺序保证优先转换大的单位
#段睿瞳 信管系
value_to_roman = {
1000: 'M', 900: 'CM', 500: 'D', 400: 'CD',
100: 'C', 90: 'XC', 50: 'L', 40: 'XL',
10: 'X', 9: 'IX', 5: 'V', 4: 'IV', 1: 'I'
}
# 构建反向映射:罗马字符 -> 数值
roman_to_value = {v: k for k, v in value_to_roman.items()}
s = input().strip()
ans_s = ''
ans_n = 0
if s[0] in roman_to_value:
i = 0
while i < len(s):
# 检查两位组合(如 IX, XL, CM 等)
if i + 1 < len(s) and s[i:i + 2] in roman_to_value:
ans_n += roman_to_value[s[i:i + 2]]
i += 2
else:
ans_n += roman_to_value[s[i]]
i += 1
print(ans_n)
else:
num = int(s)
for value, roman in value_to_roman.items():
count = num // value
ans_s += roman * count
num -= value * count
print(ans_s)可以写一个程序,先判断输入是数字串还是罗马数字串,然后分别处理:
- 罗马 → 整数
- 按照罗马数字的规则逐个字符扫描,如果当前字符比后一个字符小,则减去它,否则加上它。
- 整数 → 罗马
- 用一个从大到小的映射表(如 1000→M, 900→CM, 500→D ... ),依次减去数字,拼接对应的符号。
下面给出完整 Python 实现:
def roman_to_int(s: str) -> int:
roman_map = {
'I': 1, 'V': 5, 'X': 10, 'L': 50,
'C': 100, 'D': 500, 'M': 1000
}
total = 0
i = 0
while i < len(s):
# 判断是否是特殊情况
if i + 1 < len(s) and roman_map[s[i]] < roman_map[s[i + 1]]:
total += roman_map[s[i + 1]] - roman_map[s[i]]
i += 2
else:
total += roman_map[s[i]]
i += 1
return total
def int_to_roman(num: int) -> str:
val = [
1000, 900, 500, 400,
100, 90, 50, 40,
10, 9, 5, 4,
1
]
syms = [
"M", "CM", "D", "CD",
"C", "XC", "L", "XL",
"X", "IX", "V", "IV",
"I"
]
res = []
for i in range(len(val)):
while num >= val[i]:
num -= val[i]
res.append(syms[i])
return "".join(res)
def main():
s = input().strip()
if s[0].isdigit(): # 整数输入
num = int(s)
print(int_to_roman(num))
else: # 罗马数字输入
print(roman_to_int(s))
if __name__ == "__main__":
main()【刘存浩 25 地空】思考罗马数字怎么合理的转换为阿拉伯数字,最后想到可以倒序计数从而解决了那几种特殊情况
# 罗马数字与整数互转程序
a = input().strip()
# 映射表:整数转罗马数字(按值降序排列,包含所有特例)
int_to_roman_map = [
(1000, 'M'),
(900, 'CM'),
(500, 'D'),
(400, 'CD'),
(100, 'C'),
(90, 'XC'),
(50, 'L'),
(40, 'XL'),
(10, 'X'),
(9, 'IX'),
(5, 'V'),
(4, 'IV'),
(1, 'I')
]
# 字符映射:罗马字符到数值
roman_to_int_map = {
'I': 1,
'V': 5,
'X': 10,
'L': 50,
'C': 100,
'D': 500,
'M': 1000
}
# 判断输入类型
if a[0].isdigit():
# 输入是整数,转换为罗马数字
num = int(a)
result = ''
for value, symbol in int_to_roman_map:
count = num // value
if count > 0:
result += symbol * count
num -= value * count
print(result)
else:
# 输入是罗马数字,转换为整数
# 倒序遍历,记录前一个数值,用于判断加减
total = 0
prev_value = 0
# 从右往左处理
for char in reversed(a):
current_value = roman_to_int_map[char]
if current_value >= prev_value:
total += current_value
else:
total -= current_value
prev_value = current_value
print(total)