手撕JVAV题典——罗马数字逆向解法(暴力求解)

        作为一道经典老题,罗马数字转整数无疑是算法竞赛中简单且经典的题目,也是暴力求解极具代表性的题目之一,作为一种常见的解决问题的方式,暴力求解的核心思想就是通过枚举所有可能的解,并验证其是否满足条件来得出最终答案。

       切记,尽管暴力求解算法相对简单,但并不是所有的问题都可以使用,某些问题时间复杂程度会非常高,运行时间会非常长。因此,在实际应用中,我们通常会选择更高效的算法来解决问题。但在一些小规模的问题上,暴力求解仍然是一种可行的方法。

       题目:

罗马数字包含以下七种字符: I, V, X, LCD 和 M

字符          数值
I             1
V             5
X             10
L             50
C             100
D             500
M             1000

例如, 罗马数字 2 写做 II ,即为两个并列的 1 。12 写做 XII ,即为 X + II 。 27 写做  XXVII, 即为 XX + V + II 。

通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 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到4000不包含4000的整数,将其转换成罗马数字。

       由于要将阿拉伯数字转换成罗马数字,所以我们可以把这个数字分成千位,百位,十位,个位,分别来进行计算。

int a = x /1000;      //千位
int b = x %1000 /100; //百位
int c = x %100 /10;   //十位
int d = x %10;        //个位

      我们分别将千位,百位,十位,个位转换成罗马数字,再将其拼接即可得到结果。我们甚至不用找任何规律,直接 a==1 依次往下枚举就可以:

​
String s = "";

//千位
if(a==1) s += "M";
if(a==2) s += "MM";
if(a==3) s += "MMM";

//百位
if(b==1) s += "C";
if(b==2) s += "CC";
if(b==3) s += "CCC";
if(b==4) s += "CD";
if(b==5) s += "D";
if(b==6) s += "DC";
if(b==7) s += "DCC";
if(b==8) s += "DCCC";
if(b==9) s += "CM";

//十位
if(c==1) s += "X";
if(c==2) s += "XX";
if(c==3) s += "XXX";
if(c==4) s += "XL";
if(c==5) s += "L";
if(c==6) s += "LX";
if(c==7) s += "LXX";
if(c==8) s += "LXXX";
if(c==9) s += "XC";

//个位
if(d==1) s += "I";
if(d==2) s += "II";
if(d==3) s += "III";
if(d==4) s += "IV";
if(d==5) s += "V";
if(d==6) s += "VI";
if(d==7) s += "VII";
if(d==8) s += "VIII";
if(d==9) s += "IX";

​

         Ps:大家看到个位是不是觉得很熟悉,没错这就是我们常见钟表上的数字。

至此,我们就可以把完整的代码写出来了:

import java.util.Scanner;

public class Main {
   static String NumRoman(int x) {
		int a = x / 1000;      //千位
		int b = x % 1000 / 100; //百位
		int c = x % 100 / 10;   //十位
		int d = x % 10;        //个位​

		String s = "";
		//千位
		if (a == 1) s += "M";
		if (a == 2) s += "MM";
		if (a == 3) s += "MMM";
		//百位
		if (b == 1) s += "C";
		if (b == 2) s += "CC";
		if (b == 3) s += "CCC";
		if (b == 4) s += "CD";
		if (b == 5) s += "D";
		if (b == 6) s += "DC";
		if (b == 7) s += "DCC";
		if (b == 8) s += "DCCC";
		if (b == 9) s += "CM";
		//十位
		if (c == 1) s += "X";
		if (c == 2) s += "XX";
		if (c == 3) s += "XXX";
		if (c == 4) s += "XL";
		if (c == 5) s += "L";
		if (c == 6) s += "LX";
		if (c == 7) s += "LXX";
		if (c == 8) s += "LXXX";
		if (c == 9) s += "XC";
		//个位
		if (d == 1) s += "I";
		if (d == 2) s += "II";
		if (d == 3) s += "III";
		if (d == 4) s += "IV";
		if (d == 5) s += "V";
		if (d == 6) s += "VI";
		if (d == 7) s += "VII";
		if (d == 8) s += "VIII";
		if (d == 9) s += "IX";

		return s;
	}
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		System.out.println("请输入一个介于0-4000的整数:");
		int n = input.nextInt();
		System.out.println(NumRoman(n));
	}
 }

        于是我们可以很轻易的运行出2244对应的罗马数字 。

        逆向解法可以给我们提供更新的一些思路,例如如何判断一串罗马数字是否正确,或者正向求罗马数字怎么转换成阿拉伯数字。

     🎈🎈完结撒花🎈🎈

  • 13
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值