本文目录
题目描述
七个不同的符号代表罗马数字,其值如下:
符号 | 值 |
---|---|
I | 1 |
V | 5 |
X | 10 |
L | 50 |
C | 100 |
D | 500 |
M | 1000 |
罗马数字是通过添加从最高到最低的小数位值的转换而形成的。将小数位值转换为罗马数字有以下规则:
- 如果该值不是以 4 或 9 开头,请选择可以从输入中减去的最大值的符号,将该符号附加到结果,减去其值,然后将其余部分转换为罗马数字。
- 如果该值以 4 或 9 开头,使用 减法形式,表示从以下符号中减去一个符号,例如 4 是 5 (
V
) 减 1 (I
):IV
,9 是 10 (X
) 减 1 (I
):IX
。仅使用以下减法形式:4 (IV
),9 (IX
),40 (XL
),90 (XC
),400 (CD
) 和 900 (CM
)。 - 只有 10 的次方(
I
,X
,C
,M
)最多可以连续附加 3 次以代表 10 的倍数。你不能多次附加 5 (V
),50 (L
) 或 500 (D
)。如果需要将符号附加4次,请使用 减法形式。
给定一个整数,将其转换为罗马数字。
示例 1:
输入:num = 3749
输出: "MMMDCCXLIX"
解释:
复制代码
3000 = MMM 由于 1000 (M) + 1000 (M) + 1000 (M)
700 = DCC 由于 500 (D) + 100 (C) + 100 (C)
40 = XL 由于 50 (L) 减 10 (X)
9 = IX 由于 10 (X) 减 1 (I)
注意:49 不是 50 (L) 减 1 (I) 因为转换是基于小数位
示例 2:
输入:num = 58
输出:"LVIII"
解释:
复制代码
50 = L
8 = VIII
示例 3:
输入:num = 1994
输出:"MCMXCIV"
解释:
复制代码
1000 = M
900 = CM
90 = XC
4 = IV
个人C++解答
用贪心就可以出来
复制代码
class Solution {
public:
string intToRoman(int num) {
vector<int> value={1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
vector<string> key = { "M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I" };
string str = "";
for (int i=0; i<value.size();i++) {
while(num >= value[i]) {
str.append(key[i]);
num -= value[i];
}
}
return str;
}
};
其他解答
这道题并不难,其实按照罗马数字转整数的思路做就可以,有趣的是,这道题的评论区佬们的做法,请大家欣赏:
官方解答2:硬编码数字
回顾前言中列出的这 131313 个符号,可以发现:
千位数字只能由 M 表示;
百位数字只能由 C,CD,D 和 CM 表示;
十位数字只能由 X,XL,L 和 XC 表示;
个位数字只能由 I,IV,V 和 IX 表示。
这恰好把这 13 个符号分为四组,且组与组之间没有公共的符号。因此,整数 num 的十进制表示中的每一个数字都是可以单独处理的。
进一步地,我们可以计算出每个数字在每个位上的表示形式,整理成一张硬编码表。如下图所示,其中 0 对应的是空字符串。
利用模运算和除法运算,我们可以得到 num 每个位上的数字:
复制代码
thousands_digit = num / 1000
hundreds_digit = (num % 1000) / 100
tens_digit = (num % 100) / 10
ones_digit = num % 10
最后,根据 num 每个位上的数字,在硬编码表中查找对应的罗马字符,并将结果拼接在一起,即为 num 对应的罗马数字
复制代码
const string thousands[] = {"", "M", "MM", "MMM"};
const string hundreds[] = {"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"};
const string tens[] = {"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"};
const string ones[] = {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"};
class Solution {
public:
string intToRoman(int num) {
return thousands[num / 1000] + hundreds[num % 1000 / 100] + tens[num % 100 / 10] + ones[num % 10];
}
};
ID:“抓蚂蚁的小高手” 题解
复制代码
class Solution {
public:
string intToRoman(int num) {
string rome = "IIIVIIIXXXLXXXCCCDCCCMMM";
string ret = "";
int p = 0;
while (num > 0) {
int q = num % 10;
if (q < 4)
ret = rome.substr(p, q) + ret;
else if (q == 4)
ret = rome.substr(p + q - 2, 2) + ret;
else if (q < 9)
ret = rome.substr(p + 3, q - 4) + ret;
else
ret = rome.substr(p + 6, 2) + ret;
num /= 10;
p += 7;
}
return ret;
}
};
ID:“imp” 题解
“ipm”:“最无脑的程序,没有之一,不接受反驳(源程序太长,截取部分)”
复制代码
public String intToRoman(int num) {
String[] arr = new String[]{"","I","II","III","IV","V","VI","VII","VIII","IX","X","XI","XII","XIII","XIV","XV","XVI","XVII","XVIII","XIX","XX","XXI","XXII","XXIII","XXIV","XXV","XXVI","XXVII","XXVIII","XXIX","XXX","XXXI","XXXII","XXXIII","XXXIV","XXXV","XXXVI","XXXVII","XXXVIII","XXXIX","XL","XLI","XLII","XLIII","XLIV","XLV","XLVI","XLVII","XLVIII","XLIX","L","LI","LII","LIII","LIV","LV","LVI","LVII","LVIII","LIX","LX","LXI","LXII","LXIII","LXIV","LXV","LXVI","LXVII","LXVIII","LXIX","LXX","LXXI","LXXII","LXXIII","LXXIV","LXXV","LXXVI","LXXVII","LXXVIII","LXXIX","LXXX","LXXXI","LXXXII","LXXXIII","LXXXIV","LXXXV","LXXXVI","LXXXVII","LXXXVIII","LXXXIX","XC","XCI","XCII","XCIII","XCIV","XCV","XCVI","XCVII","XCVIII","XCIX","C","CI","CII","CIII","CIV","CV","CVI","CVII","CVIII","CIX","CX","CXI","CXII","CXIII","CXIV","CXV","CXVI","CXVII","CXVIII","CXIX","CXX","CXXI","CXXII","CXXIII","CXXIV","CXXV","CXXVI","CXXVII","CXXVIII","CXXIX","CXXX","CXXXI","CXXXII","CXXXIII","CXXXIV","CXXXV","CXXXVI"
};
return arr[num];
}
ID:“Yimi” 题解
“Yimi”:“啊我写的好长,思路跟官方的 方法二:硬编码数字 一致”
复制代码
class Solution {
public:
string intToRoman(int num) {
string ans = "";
int M = num / 1000;
num %= 1000;
int C = num / 100;
num %= 100;
int X = num / 10;
num %= 10;
int I = num;
num %= 1;
switch (M) {
case 3:
ans += 'M';
case 2:
ans += 'M';
case 1:
ans += 'M';
case 0:
break;
}
switch (C) {
case 9:
ans += "CM";
break;
case 8:
ans += "DCCC";
break;
case 7:
ans += "DCC";
break;
case 6:
ans += "DC";
break;
case 5:
ans += "D";
break;
case 4:
ans += "CD";
break;
case 3:
ans += 'C';
case 2:
ans += 'C';
case 1:
ans += 'C';
case 0:
break;
}
switch(X) {
case 9:
ans += "XC";
break;
case 8:
ans += "LXXX";
break;
case 7:
ans += "LXX";
break;
case 6:
ans += "LX";
break;
case 5:
ans += "L";
break;
case 4:
ans += "XL";
break;
case 3:
ans += 'X';
case 2:
ans += 'X';
case 1:
ans += 'X';
case 0:
break;
}
switch(I) {
case 9:
ans += "IX";
break;
case 8:
ans += "VIII";
break;
case 7:
ans += "VII";
break;
case 6:
ans += "VI";
break;
case 5:
ans += "V";
break;
case 4:
ans += "IV";
break;
case 3:
ans += 'I';
case 2:
ans += 'I';
case 1:
ans += 'I';
case 0:
break;
}
return ans;
}
};
ID:"Happy Grothendieckcvx"题解
"Happy Grothendieckcvx":用不了一点枚举 没有四千限制也能打
复制代码
string intToRoman(int num) {
map<int,char> roma;
roma.insert(pair<int,char>(6,'M'));
roma.insert(pair<int,char>(5,'D'));
roma.insert(pair<int,char>(4,'C'));
roma.insert(pair<int,char>(3,'L'));
roma.insert(pair<int,char>(2,'X'));
roma.insert(pair<int,char>(1,'V'));
roma.insert(pair<int,char>(0,'I'));
string sorted;
for(int i=4;i>0;i--){
int temp=num%(int)pow(10,i)/(int)pow(10,i-1);
if(temp==9){
sorted+=roma[i*2-2];
sorted+=roma[i*2];
continue;
}
if(temp==4){
sorted+=roma[i*2-2];
sorted+=roma[i*2-1];
continue;
}
if(temp>=5){
sorted+=roma[i*2-1];
temp-=5;
}
for(int j=0;j<temp;j++){
sorted+=roma[i*2-2];
}
}
return sorted;
}