题目: 传送门
题意: 将一个数字转换成罗马数字,数字的转换,神奇而又充满了趣味。
首先:
然后在让我们看一下罗马数字的规则:
1、罗马数字的符号一共只有7个:I(代表1)、V(代表5)、X(代表10)、L(代表50)、C代表100)、D(代表500)、M(代表1,000)。这7个符号位置上不论怎样变化,它所代表的数字都是不变的。
2、一个罗马数字符号重复几次,就表示这个数的几倍。如:"III"表示"3";"XXX"表示"30"。
3、在罗马数字的上方加上一条横线或者加上下标的M,表示将这个数乘以1000,即是原数的1000倍;同理,如果上方有两条横线,即是原数的1000000(10002)倍。
4、同一数码最多只能出现三次,如40不可表示为XXXX,而要表示为XL。由于IV是古罗马神话主神朱庇特(即IVPITER,古罗马字母里没有J和U)的首字,因此有时用IIII代替Ⅳ。
我要知道他的转化规则其实就是分别表示某一位,例如1994,表示的分别是1000、900、90、4,而不是1、9、9、4。现在我们知道规则了,并且题目中数字的范围是小于3999的,那么我们就可以进行转换了,我首先是暴力,数位分离,我们看代码:
#include<iostream>
using namespace std;
class Solution {
public:
string intToRoman(int num);
};
string Solution::intToRoman(int num) {
string s;
int x = 1000;
while (x) {
int k = num / x;
if (k == 0) {
x /= 10;
continue;
}
if (x == 1000) {
for (int i = 1; i <= k; i++) {
s.push_back('M');
}
}
else if (x == 100) {
if (k == 9) {
s.push_back('C');
s.push_back('M');
}
else if (k >= 5) {
s.push_back('D');
for (int i = 1; i <= k - 5; i++)
s.push_back('C');
}
else if (k == 4) {
s.push_back('C');
s.push_back('D');
}
else {
for (int i = 1; i <= k; i++) {
s.push_back('C');
}
}
}
else if (x == 10) {
if (k == 9) {
s.push_back('X');
s.push_back('C');
}
else if (k >= 5) {
s.push_back('L');
for (int i = 1; i <= k - 5; i++)
s.push_back('X');
}
else if (k == 4) {
s.push_back('X');
s.push_back('L');
}
else {
for (int i = 1; i <= k; i++) {
s.push_back('X');
}
}
}
else {
if (k == 9) {
s.push_back('I');
s.push_back('X');
}
else if (k >= 5) {
s.push_back('V');
for (int i = 1; i <= k - 5; i++)
s.push_back('I');
}
else if (k == 4) {
s.push_back('I');
s.push_back('V');
}
else {
for (int i = 1; i <= k; i++) {
s.push_back('I');
}
}
}
num %= x;
x /= 10;
}
return s;
}
int main() {
int num;
cin >> num;
Solution s;
cout << s.intToRoman(num) << endl;
return 0;
}
但是我们能够发现,函数有很多重复的if,可以提取出来封装成一个函数,来使程序更加简洁。
我们看代码:
#include<iostream>
using namespace std;
class Solution {
public:
string intToRoman(int num);
void giegie(string& s, int k, char q, char z, char g);///s存放结果的字符串必须使用引用或者指针,我们希望能够保存更新结果
};
string Solution::intToRoman(int num) {
string s;
int x = 1000;
while (x) {
int k = num / x;
if (k == 0) {
x /= 10;
continue;
}
if (x == 1000) {
giegie(s, k, 'A', 'A', 'M');//没有5000,10000用A代替
}
else if (x == 100) {
giegie(s, k, 'M', 'D', 'C');
}
else if (x == 10) {
giegie(s, k, 'C', 'L', 'X');
}
else {
giegie(s, k, 'X', 'V', 'I');
}
num %= x;
x /= 10;
}
return s;
}
void Solution::giegie(string& s, int k, char q, char z, char g) {
if (k == 9) {
s.push_back(g);
s.push_back(q);
}
else if (k >= 5) {
s.push_back(z);
for (int i = 1; i <= k - 5; i++)
s.push_back(g);
}
else if (k == 4) {
s.push_back(g);
s.push_back(z);
}
else {
for (int i = 1; i <= k; i++) {
s.push_back(g);
}
}
return ;
}
int main() {
int num;
cin >> num;
Solution s;
cout << s.intToRoman(num) << endl;
return 0;
}