返回列表 發帖

下次題目-a013: 羅馬數字

http://zerojudge.tw/ShowProblem?problemid=a013

如果生活在數世紀之前的古羅馬,你應該用過 V 來表示五。V 和 5 這兩個符號都可以用來表示數目五。用來表示數目的符號稱作數字。而羅馬人用來表示數目的符號就是羅馬數字。

以下是七個基本的羅馬數字︰



羅馬數字        數目
I        1
V        5
X        10
L        50
C        100
D        500
M        1,000
所有其他的數目都是由這些數字組合而成。數目都是由左寫到右,通常值是等於組成的羅馬數字加起來。

例如十七可以表示為



X+V+I+I=XVII
10+5+1+1=17
表示羅馬數字可以使用減法來取代加法的規則。例如四可以不用四個一相加來表示 IIII,而採用五減一來表示 IV。利用這類規則,羅馬人能夠減化許多數目的表示方式,例如 IX 取代 VIIII 表示 9,及 CD 取代 CCCC 表示 400。

今日我們並不確定羅馬符號的起源為何。例如符號 V 的起源主要有兩個理論。有些學者認為五最早是用握拳、拇指在外的手勢來表示。最後以象形文字書寫而簡化為 V。

另一個理論認為 X 源自在 10 條線加上交叉線。因此五可以表示為 X 的一半,或是 V。

羅馬數字可以很容易地用來相加或相減,但算起乘除法就相當不順手。這就是為什麼現在羅馬數字並不常用的原因了。

問題
然而,羅馬數字還是經常用於書本章節及頁碼的編號。在這一題工作是讀入兩個正整數,然後輸出兩個數字差的絕對值。所有的數字都必須以羅馬數字來表示。而連續四個相同符號出現時,必須用減法規則來化簡之。







輸入說明 :
每個輸入檔中會有一個或以上的測試資料。每一行由兩個數字組成一筆測試資料,且所有數字將會小於4,000。檔案最後會以符號 # 表示結束。
輸出說明 :
每筆測試資料的答案必須輸出到檔案中,並且換行。如果答案為零,則須輸出字串 ZERO。
範例輸入 :

I I MM II #
範例輸出 :

ZERO MCMXCVIII

  1. #include <iostream>
  2. #include <string>
  3. #define N 7

  4. using namespace std;

  5. char roman[N] = {'M', 'D', 'C', 'L', 'X', 'V', 'I'};
  6. int arabic[N] = {1000, 500, 100, 50, 10, 5, 1};

  7. int iabs(const int& t);
  8. int to_arabic(string t);
  9. int to_arabic(char c);
  10. string to_roman(int t);

  11. int main()
  12. {
  13.     for(;;)
  14.     {
  15.         string t1, t2;
  16.         cin >> t1;
  17.         
  18.         if(t1[0] == '#')
  19.             break;
  20.         else
  21.             cin >> t2;
  22.         
  23.         cout << to_roman(iabs(to_arabic(t1) - to_arabic(t2))) << endl;
  24.     }
  25.    
  26.     return 0;
  27. }

  28. inline int iabs(const int& t)
  29. {
  30.     return (t > 0)? t : -t;
  31. }
  32. inline int to_arabic(string t)
  33. {
  34.     int len = t.length(), array[len];
  35.    
  36.     for(int i = 0; i < len; i++)
  37.         array[i] = to_arabic(t[i]);
  38.    
  39.     len--;
  40.    
  41.     int tmp = array[len];
  42.    
  43.     for(int i = 0; i < len; i++)
  44.     {
  45.         if(array[i] < array[i+1])
  46.             tmp -= array[i];
  47.         else
  48.             tmp += array[i];
  49.     }
  50.    
  51.     return tmp;
  52. }
  53. inline int to_arabic(char c)
  54. {
  55.     for(int i = 0; i < N; i++)
  56.         if(c == roman[i])
  57.             return arabic[i];
  58. }
  59. inline string to_roman(int t)
  60. {
  61.     if(t == 0)
  62.         return "ZERO";
  63.    
  64.     string tmp;
  65.    
  66.     for(int j = 0; j < N; j += 2)
  67.     {
  68.         int k = t / arabic[j];
  69.         
  70.         if(k == 9)
  71.             tmp.push_back(roman[j]), tmp.push_back(roman[j-2]);
  72.         else if(k == 4)
  73.             tmp.push_back(roman[j]), tmp.push_back(roman[j-1]);
  74.         else
  75.         {
  76.             if(k > 4)
  77.                 tmp.push_back(roman[j-1]), k -= 5;
  78.             
  79.             for(int i = k; i > 0; i--)
  80.                 tmp.push_back(roman[j]);
  81.         }
  82.         
  83.         t %= arabic[j];
  84.     }
  85.    
  86.     return tmp;
  87. }
複製代碼

TOP

不會大家都複製貼上吧
Mai  買大誠 [E-Mail : mainword@dlinfo.tw, mainword@gmail.com] 手機 : 0911-116194
Sun Certified Java Programmer

DL Info 鼎侖資訊 [886-7-969-0998] 高雄市苓雅區光華一路206號6樓之2

TOP

返回列表