高中生解題系統 A013.羅馬數字

心得:

這題大概解了兩天,大概8小時(哭...),一開始看完題目後,感覺蠻簡單,結果沒看仔細,漏了一些題目要求,(這些後來,在解題中都慢慢發現也去改正了),不過用那麼長的時間去解題,解出來之後成就感真的超大。雖然中途放棄,跑去看別人的解題思路,然後還看不懂~哈,但是隔天起床好像突然就懂了,然後就模擬別人的解題思路,去寫出程式碼
參考:https://dctimelearninghowtocode.blogspot.com/2020/01/zerojudge-a013-python.html


解題思路:

題目要求我們求出兩組羅馬數字的差的絕對值,若是0就輸出ZERO,然後把題目給的範例羅馬數字輸出 MCMXCVIII,轉成阿拉伯數字,會是1000+(-100)+1000+(-10)+100+5+1+1+1,為什麼有些數字是負數呢?  
因為如果在羅馬數字中,有一個特別的規定,若是一個數字出現超過三次就要用減法來表示
舉例:
  • I=1
  • V=5
  • X=10
  • L=50
  • C=100
  • D=500
  • M=1000
若是要表示三,羅馬數字會是III,若是要表示四,羅馬數字不能是IIII,因為上面有說,一個羅馬數字不能重複出現超過三次以上,那要怎麼表示呢?
答案是:IV(就是-1+5)

以上是如何把使用者輸入的羅馬數字轉換成我們所使用的阿拉伯文字,然後題目要求我們算出使用者所輸入兩筆阿拉伯數字差的絕對值,最後把算出來的答案轉成羅馬數字輸出

程式碼:


#處理使用者所輸入的羅馬數字(每次只取一筆)
def conduct_romnumber(num):

  #基本羅馬數字對應的阿拉伯數字
  rom_number = {"I":1,"V":5,"X":10,"L":50,"C":100,"D":500,"M":1000}

  #用來裝分割後的字串(下面會分割)
  num_list = []

  #儲存算出來的阿拉伯數字
  sum = 0

  #將字串分割成一個字一個字(例如:"MI",分割後變成"M","I"),分割後儲存在list中
  for i in num:
    num_list.append(i)
  #如果num_list裡面的字串和rom_number裡的key相同,就會去rom_number裡抓對應的value
  #並且對應到的阿拉伯數字會替換掉原本儲存在num_list的羅馬數字  for k in range(0,len(num_list)):
    num_list[k]=rom_number[num_list[k]]
  #如果num_list裡的前一個值小於後一個值,前一個值就變負數(羅馬數字的規則)
  for j in range(1,len(num_list)):
    if num_list[j-1] < num_list[j]:
      num_list[j-1]= - num_list[j-1]

  #將num_list裡的阿拉伯數字分別加入sum
  for m in num_list:
    sum+=m

  #回傳sum
  return sum
#把算出來的絕對值差,轉回羅馬數字
def turn_number(number_abs):
  #如果數字大於一千,就執行,且可以算出有幾個M
  if number_abs>=1000:
    #count1000是用來儲存M有幾個的變數
    count1000 = 0
    while number_abs>=1000:
      count1000 =number_abs//1000
      #number_abs是儲存絕對值差的變數
      #然後新的變數會等於原本的變數的餘數,這樣才能繼續跑下面的程式
      number_abs = number_abs%1000
    if count1000<4:
      for i in range(count1000):
        print("M",end = '')
    
#下面跟處理1000是一樣的思路      
  if number_abs>=100:
    count100 = 0

    while number_abs>=100:
      count100 =number_abs//100
      number_abs = number_abs%100
    if count100<=3:
      for i in range(count100):
        print("C",end = '')
    if count100==4:
      print("CD",end = '')
    if count100>=5 and count100<9:
      print("D",end = "")
      for n in range(count100-5):
        print("C",end = '')
    if count100==9:
      print("CM",end ='')
      
  if number_abs>=10:
    count10 = 0

    while number_abs>=10:
      count10 = number_abs//10
      number_abs = number_abs%10
    if count10<=3:
      for i in range(count10):
        print("X",end = '')
    if count10==4:
      print('XL',end="")
    if count10>=5 and count10<9:
      print("L",end='')
      for n in range(count10-5):
        print("X",end = '')
    if count10==9:
      print("XC",end ='')

  if number_abs!=0:
    count = 0
    count = number_abs//1
    if count <=3:
      for i in range(count):
        print("I"*count,end = '')
    if count==4:
      print("IV",end = '')
    if count>=5 and count<9:
      print("V",end = '')
      for n in range(count-5):
        print("I",end = '')
    if count ==9:
      print("IX",end = '')

while True:
  #一直執行,直到使用者輸入"#",就跳出迴圈(題目要求)
  a = input()
  if a =="#":
    break
  #使用者一次輸入兩筆資料,用空格來區別
  a_list = a.split(" ")

  #將兩筆資料分別給X1及X2兩個變數
  x1 = a_list[0]
  x2 = a_list[1]
  #ans是絕對值差(把X1及X2分別帶進並處理成阿拉伯數字後,相減算出ans)
  ans = conduct_romnumber(x1)-conduct_romnumber(x2)
  #如果ans小於0,就套上絕對值(abs)
  if ans<0:
    ans =abs(ans)
  #題目說等於0,輸出ZERO
  if ans==0:
    print("ZERO",end="")
  #如果算出來的絕對值差不等於零,就帶入處理成羅馬數字輸出
  else:
    turn_number(ans)
  #格式所需
  print()





留言

這個網誌中的熱門文章

高中生解題系統 A017. 五則運算

python小遊戲:看誰的追蹤人數比較多