Zerojudge 基礎題庫a013 羅馬數字 (Python)
一、題目重述
這題真的需要好好講一下,因為題目敘述真的好長。我重新敘述一下題目好了:
輸入: 兩個羅馬數字
輸出: 一個羅馬數字,值為輸入的兩值相減
二、解法大綱
首先,羅馬數字只是用來單純標示他的值,無法做計算而且電腦只看得懂阿拉伯數字,所以在做計算時,須先把羅馬轉成阿拉伯
因為題目是輸入兩個羅馬數字,無法直接做相減的動作,所以第一步先把羅馬轉成阿拉伯。
轉成阿拉伯後,就可以相減了,記得加絕對值,因為題目說可能第一數比較小。
計算出答案後,最後把它變成羅馬數字,就可以了。
三、解法問題
有兩個問題,也就是題目的主要部分。
1.羅馬轉成阿拉伯
我們先來觀察一個羅馬數字:
III
我想聰明的你,這一定是三,那我問: 你怎麼知道?
我先給一下轉換表:
- I 1
- V5
- X10
- L50
- C100
- D500
- M1000
好,回來正題,III可以看成是 I + I + I
轉換後也就是 1 + 1 + 1,答案是3
再一個羅馬數字
IV
如果你用上面的方法,1 + 5 = 6,可是答案是四耶~
那是因為羅馬數字有一個特殊的規則,數碼限制:同一數碼最多只能連續出現三次,如40不可表示為XXXX,而要表示為XL
(羅馬數字 - 維基百科)
如果我們使用IIII來表示4,感覺I太多了,所以用IV來表示,意思是 5 - 1
換一個方式來表達,也就是 -1 + 4
那 MCDXXXVII 呢?我們先把一個一個分開來,變成:M, C, D, X, X, X, V, I, I
接下來,一一轉成數字,變成: 1000, 100, 500, 10, 10, 10, 5, 1, 1
接著,我們使用一個小伎倆:
在較大的羅馬數字的左邊記上較小的羅馬數字,表示大數字減小數字
我們先找右邊數字比自己大的,找到就把它變成負的
1000, 100, 500, 10, 10, 5, 1, 1
1000右邊是100,比1000小,不變成負的,下一個
100右邊是500,比100大,把它變成負的(100 => -100)
500右邊是10,比500小,不變成負的,下一個
就這樣一直到倒數第二個,最後數列為:
1000, -100, 500, 10, 10, 5, 1, 1
把全部加總:
1000 + (-100) + 500 + 10 + 10 + 5 + 1 + 1 = 1437
1437 就是 MCDXXXVII 啦~
2.阿拉伯轉成羅馬
接下來我們來看1437如何轉成羅馬數字
我們先把1437看成1000 + 400 + 30 + 7
1000用羅馬數字是M
400是CD
30是XXX
7是VII
所以用羅馬數字就是MCDXXXVII
我把所有可能的數字都寫在下面:
千位:
1000 => M
2000 => MM
3000 => MMM
百位:
100 => C
200 => CC
300 => CCC
400 => CD
500 => D
600 => DC
700 => DCC
800 => DCCC
900 => CM
十位:
10 => X
20 => XX
30 => XXX
40 => XL
50 => L
60 => LX
70 => LXX
80 => LXXX
90 => LC (是XC,感謝Unknown糾正 .w.)
個位:
1 => I
2 => II
3 => III
4 => IV
5 => V
6 => VI
7 => VII
8 => VIII
9 => IX
四、程式碼
好,相信你已經沒問題了
Python 程式碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | def translate_to_numbers(num): '''將羅馬數字轉換成阿拉伯數字''' # numbers : 轉換規則 numbers = {'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000} # x1_list : 存放轉換計算過程 x1_list = [] # sum1 : 轉換後的阿拉伯數字 sum1 = 0 # 將羅馬數字轉換成串列 for i in num: x1_list.append(i) # 將各個羅馬數字變成數字,使用numbers字典 for i in range(len(x1_list)): # 0 ~ x1_list end (int) x1_list[i] = numbers[x1_list[i]] # 尋找需要使用減法的數字 for i in range(1, len(x1_list)): # 1 ~ x1_list end (int) if x1_list[i - 1] < x1_list[i]: x1_list[i - 1] = -x1_list[i - 1] # 把計算過程全部加總起來,放入sum1 for i in range(len(x1_list)): sum1 += x1_list[i] # 回傳答案 return sum1 def roma(num): '''將阿拉伯數字轉換成羅馬數字''' # x : 問題 x = num # 分別存入千、百、十、個位數到thousand,hundred,ten,one裡 thousand = x // 1000 hundred = x % 1000 // 100 one = x % 10 ten = (x % 100 - one) // 10 # 將千位數以羅馬數字輸出 if thousand != 0: for i in range(thousand): print('M', end="") # 將百位數以羅馬數字輸出 if hundred != 0: if hundred <= 3: for i in range(hundred): print('C', end="") if hundred == 4: print("CD", end="") if hundred >= 5 and hundred != 9: print("D", end="") for i in range(hundred - 5): print("C", end="") if hundred == 9: print("CM", end="") # 將十位數以羅馬數字輸出 if ten != 0: # ten output if ten <= 3: for i in range(ten): print('X', end="") if ten == 4: print("XL", end="") if ten >= 5 and ten != 9: print("L", end="") for i in range(ten - 5): print("X", end="") if ten == 9: print("XC", end="") # 將個位數以羅馬數字輸出 if one != 0: if one <= 3: for i in range(one): print('I', end="") if one == 4: print("IV", end="") if one >= 5 and one != 9: print("V", end="") for i in range(one - 5): print("I", end="") if one == 9: print("IX", end="") while 1: x1 = input() # 當輸入為#時結束程式 if x1 == '#': break # 把輸入弄成我們需要的資訊(兩個羅馬數字) question = x1.split() x1 = question[0] x2 = question[1] # 兩個數字相減 ans1 = translate_to_numbers(x1) - translate_to_numbers(x2) # 做絕對值的動作 if ans1 < 0: ans1 = -ans1 # 當答案是0時輸出ZERO if ans1 == 0: print("ZERO", end="") else: roma(ans1) # 換行(格式需求) print() |
90 => XC 才對唷
回覆刪除阿呀,寫錯了 .W. 感謝糾正
刪除