闲聊蓝桥杯JAVA - 罗马数字

本文介绍了一种将罗马数字转换为十进制数的算法,并详细解释了罗马数字的构成规则和特殊情况处理方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

罗马数字

D:这道题解法不难,但是主要是研究对于特殊值我们的处理方式:

    古罗马帝国开创了辉煌的人类文明,但他们的数字表示法的确有些繁琐,尤其在表示大数的时候,现在看起来简直不能忍受,所以在现代很少使用了。之所以这样,不是因为发明表示法的人的智力的问题,而是因为一个宗教的原因,当时的宗教禁止在数字中出现0的概念!
    罗马数字的表示主要依赖以下几个基本符号:
    I  1
    V  5
    X  10
    L  50
    C  100
    D  500
    M  1000
    这里,我们只介绍一下1000以内的数字的表示法。
单个符号重复多少次,就表示多少倍。最多重复3次。比如:CCC表示300  XX表示20,但150并不用LLL表示,这个规则仅适用于I X C M。
    如果相邻级别的大单位在右,小单位在左,表示大单位中扣除小单位。比如:IX表示9  IV表示4  XL表示40 更多的示例参见下表,你找到规律了吗?

I,1 
II,2
III,3
IV,4
V,5
VI,6
VII,7
VIII,8
IX,9 

X,10
XI,11
XII,12
XIII,13
XIV,14
XV,15
XVI,16
XVII,17
XVIII,18
XIX,19
XX,20
XXI,21
XXII,22
XXIX,29
XXX,30
XXXIV,34
XXXV,35
XXXIX,39
XL,40
L,50
LI,51
LV,55
LX,60
LXV,65
LXXX,80
XC,90
XCIII,93
XCV,95
XCVIII,98
XCIX,99

C,100
CC,200
CCC,300
CD,400
D,500
DC,600
DCC,700
DCCC,800
CM,900
CMXCIX,999

    本题目的要求是:请编写程序,由用户输入若干个罗马数字串,程序输出对应的十进制表示。
    输入格式是:第一行是整数n,表示接下来有n个罗马数字(n<100)。以后每行一个罗马数字。罗马数字大小不超过999。

要求程序输出n行,就是罗马数字对应的十进制数据。
例如,用户输入:
3
LXXX
XCIII
DCCII

则程序应该输出:
80
93
702

注意:
    请仔细调试!您的程序只有能运行出正确结果的时候才有机会得分!
    在评卷时使用的输入数据与试卷中给出的实例数据可能是不同的。

Z:这道题考的数字进制的转化。

理解起来不难,但是难点将在于 进1的处理 和 对4,9的处理 上。

【规律1】罗马数字的进1,是重复数字:

C,100
CC,200
CCC,300

【规律2】对靠近值得处理,相邻级别的大单位在右,小单位在左,表示大单位中扣除小单位:

XIII,13
XIV,14
XV,15

XCIX,99

【元素1】而基本数字单位是1 , 5的倍数:

    I  1
    V  5
    X  10
    L  50
    C  100
    D  500
    M  1000

M:那对于规律1和规律2交叉使用,要怎么区别出符号代表的数字值呢?

Z:规律2的使用的情况是有限,所以可以使用穷举把串中的涉及规律2的值算出来,再算规律1的值。(也可以反过来)

可以分规律2和规律1两次对值进行转化,建立在以下的条件:一串数字可以分成多块,每块之间都是相互独立的,没有绝对位置的要求:

CMXCIX = CM XC IX = 900 90 9 = 999

而阿拉伯数字中 :123 如果把20先去掉,变成13,数值就完全不同了

M:我仍然无法确定其规律,按目前理解一个阿拉巴数字用罗马数字是有多种表示方式的。例如XCIX = 99,那我是否也能用IC = 99 。这样的话我不是得把所有 小数+大数 都列举出来进行筛选?

Z:你漏读了题目,如果相邻级别的大单位在右,小单位在左,表示大单位中扣除小单位。
所谓的相邻级别就是

级别一
I  1
级别二 个位及10
V  5
X  10
级别三 十位及100
L  50
C  100
级别四 百位及1000
D  500
M  1000

而A是最高位为5的数,大数 - A = A ,所以A不用在规律2中。(像20-5=55,500-50=450等)

剩下的规律2组合就有:IV , IX , XL , XC , CD , CM

Z:实现代码如下:

import java.util.Scanner;

public class Test {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int num = input.nextInt();
        String[] arr = new String[num];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = input.next();
        }
        for (int i = 0; i < arr.length; i++) {
            System.out.println(change(arr[i]));
        }
    }

    private static int change(String st) {
        int result = 0;
        for (int i = 0; i < st.length(); i++) {
            if(st.charAt(i) == 'I'){
                result += 1;
            }else if(st.charAt(i) == 'V'){
                result += 5;
            }else if(st.charAt(i) == 'X'){
                result += 10;
            }else if(st.charAt(i) == 'L'){
                result += 50;
            }else if(st.charAt(i) == 'C'){
                result += 100;
            }else if(st.charAt(i) == 'D'){
                result += 500;
            }else if(st.charAt(i) == 'M'){
                result += 1000;
            }
        }

        //处理成对数
        if(st.indexOf("IV") >= 0){
            result -= 2;
        }
        if(st.indexOf("IX") >= 0){
            result -= 2;
        }
        if(st.indexOf("XL") >= 0){
            result -= 20;
        }
        if(st.indexOf("XC") >= 0){
            result -= 20;
        }
        if(st.indexOf("CD") >= 0){
            result -= 200;
        }
        if(st.indexOf("CM") >= 0){
            result -= 200;
        }
        return result;
    }
}   

M:处理成对的时候,像IV为什么要减去2之类的,不是1么?

Z:因为IV本来就是-1的操作,而实际上我们算成了+1,比目标值多出了2,所以需要-2。

M:如果这种处理成对的方式出现了叠加,那怎么办?像IXL这样的数,即减去了2,又减去20。

Z:前面说了罗马数字没有绝对位置,但并不表示数字之间可以随意交换位置。只是可以删去,增加特定数字。

罗马数字有一个相对位置的概念,大的数字相对小的数字应该放在前面,所以像IX是比L小的,不可能出现IXL这样的数,不用考虑重叠的情况。这都需要从数字的观察中得到。

M:总结这道题

  1. 首先要了解其遵循的规则。
  2. 根据规则的特性,结合实例的特点,总结出罗马数字暗含的规律:数字相互独立,有相对顺序
  3. 利用规律模拟出相应的转化算法

主要还是需要冷静读清题意,尝试分析。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值