1044 火星数字

1044 火星数字 (20 分)

题意描述:

火星人是以 13 进制计数的:

  • 地球人的 0 被火星人称为 tret。
  • 地球人数字 1 到 12 的火星文分别为:jan, feb, mar, apr, may, jun, jly, aug, sep, oct, nov, dec。
  • 火星人将进位以后的 12 个高位数字分别称为:tam, hel, maa, huh, tou, kes, hei, elo, syy, lok, mer, jou。
    例如地球人的数字 29 翻译成火星文就是 hel mar;而火星文 elo nov 对应地球数字 115。

为了方便交流,请你编写程序实现地球和火星数字之间的互译。

输入格式:
输入第一行给出一个正整数 N(<100),随后 N 行,每行给出一个 [0, 169) 区间内的数字 —— 或者是地球文,或者是火星文。

输出格式:
对应输入的每一行,在一行中输出翻译后的另一种语言的数字。

输入样例:
4
29
5
elo nov
tam
输出样例:
hel mar
may
115
13


解题思路:

Alice: 你感觉怎么样 ?
Bob: 太棒了 !
Alice: 什么太棒 了!,╭(╯^╰)╮, 我是问你这道题目怎么样,你想啥呢 !
Bob: 啊, 这道题啊,没啥的。逻辑上复杂一点,不过没有什么难度。
Alice: (゚Д゚#) 哪里复杂了,挺简单的啊。你看,不就是先 判断输入的是火星文数字还是地球数字,如果是地球数字就变成火星文数字,如果是火星文数字就变成地球数字,然后输出嘛。
Bob:恩,不错不错,main( )函数就应该这么写。
Alice: 然后具体的话, 地球数字转换为火星文,如果是0就直接返回‘tret’,不是零的就先求出这个地球数字的13进制的十位和个位。然后
Bob: 等等,ヽ(゚Д゚)ノ怎么13进制的十位和个位??13进制也能叫做十位和个位???
Alice: 就这样称呼嘛,就是倒数第二位和第一位啊。你看题目给的范围,[0 169)转换成13进制的时候最多也就两位数字了。然后就按照题目中给的映射,把13进制数字换成火星文就好了。
Bob: 还有什么要补充的吗 ?
Alice:有啊,地球数字变成火星文的时候没有“前导零”, 也没有“后缀零”。火星文变成地球数字的时候,有可能只有一位火星数字,这时候需要进一步判断这一位火星数字对应的是十位还是个位。
Bob: 可以啊,这逻辑,简直滴水不漏 啊。
Alice: 那是,ヾ(๑╹◡╹)ノ"
Bob: ヽ(゚∀゚)メ(゚∀゚)ノ


代码:

def main():
    N = int(input())
    # 接收 整数 N
    for x in range(N):
        temp = input()
        # 每次读入一个数字
        if is_number(temp[0]):
            # 如果这个数字是地球数字,就把它变成火星数字然后输出
            print(earth2mars(temp))
        else:
            # 如果这个数字是火星数字,就把它变成地球数字然后输出
            print(mars2earth(temp))


def earth2mars(temp):
    # 把地球数字变成火星数字,输入是地球数字的字符串表示,输出是火星数字的字符串表示。
    number = int(temp)
    if number == 0:
        return 'tret'
        # 如果输入的数字是0, 对应火星文中的 tret
    else:
        # 如果非零,与[1, 168]之间的地球数字对应的火星文中不再有‘tret’出现。
        ones = number % 13
        tens = number // 13
        # 由于输入地球数字的范围是[1, 168],也就是说最多对应两位的火星文。所以先分别求出两位火星文对应的数字。
        # 因为火星文数字直接对应的是地球上的13进制,所以先得到地球数字的13进制表示。
        # ones表示13进制的个位数,tens表示13进制的十位数。
        ones_dict = dict(zip([x for x in range(1, 13)], [
            'jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jly', 'aug', 'sep', 'oct', 'nov', 'dec']))
        tens_dict = dict(zip([x for x in range(1, 13)], [
            'tam', 'hel', 'maa', 'huh', 'tou', 'kes', 'hei', 'elo', 'syy', 'lok', 'mer', 'jou']))
        #  用字典建立起地球13进制数 到 火星文数字的映射,由于火星文的奇葩规定,个位上的数字和十位上的数字分别建立了两个映射。

        if tens in tens_dict:
            # 如果能成功映射(tens == 0 时 不能成功映射),就把地球数字13进制的十位数转换为火星文数字
            tens = tens_dict[tens]
        else:
            tens = ''
            # 根据题意,tens == 0时,要对应 '' 而不是 'tret'。
        if ones in ones_dict:
            ones = ones_dict[ones]
        else:
            ones = ''

    return "{} {}".format(tens, ones).strip()
    # 将tens和ones填入字符串,由于tens和ones可能是空字符串,这样就会在答案字符串的首部或者尾部有多余的空格出现。
    # 所以我们需要strip()来去除多余的空格。


def mars2earth(temp):
    # 把火星数字变成地球数字,输入是火星数字的字符串表示,输出是地球数字。
    if temp == 'tret':
        return 0
        # 如果输入是'tret'就是地球数字的零啦。
    else:
        ones_dict = dict(zip(['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jly',
                              'aug', 'sep', 'oct', 'nov', 'dec'], [x for x in range(1, 13)]))
        tens_dict = dict(zip(['tam', 'hel', 'maa', 'huh', 'tou', 'kes', 'hei',
                              'elo', 'syy', 'lok', 'mer', 'jou'], [x for x in range(1, 13)]))
        # 建立起火星文数字到地球数字的映射,注意这里的映射和上面函数中映射刚好是相反的。
        temp = temp.split(" ")
        # 只能是temp.split(" "),如果写成temp.split()就会把只有一个数位的火星文拆开,如tam -> 't','a','m'
        if len(temp) == 2:
            #如果有两位数字的话, 分别将其映射会地球数字的十位和个位 
            tens = tens_dict[temp[0]]
            ones = ones_dict[temp[1]]
        elif len(temp) == 1:
            # 如果只有一位数字,那它既可能是个位数也可能是十位数。
            if temp[0] in tens_dict:
                # 如果这个数字是十位数,映射为十位数,而且此时个位数是0。
                tens = tens_dict[temp[0]]
                ones = 0
            else:
                # 如果这个数字是个位数,映射为个位数,而且此时十位数是0。
                tens = 0
                ones = ones_dict[temp[0]]

    return tens * 13 + ones
    # 把得到的13进制数的十位和个位组合成10进制整数。


def is_number(char):
    """判断一个字符是否是数字字符"""
    return char in "0123456789"


if __name__ == '__main__':
    main()


易错点:

  • 火星文数字是13进制的,所以在和地球数字的互换中要先变成13进制的,才好建立起映射。
  • 火星文数字中只有个位上的零,没有前导零,也没有十位上一个数字个位上跟着一个零的情况。这都是因为火星文中个位数字用了一套字符,十位数字用了另一套字符。

总结:

  • 判断一个字符是否是数字字符至少有两种写法:

    return char in '0123465798' # method 1
    return ord(char) <= ord('9') and ord(char) >= ord('0') method 2
    
  • 10 进制转换为其他进制 的方法有: 除K取余法

  • 用字典将一个列表和其下标建立起映射关系:

    maps = dict(zip(range(len(object_list)), object_list))
    其实质是使用zip函数( ) 和两个列表生成字典。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值