2010年5月14日 星期五

Problem 11616 Roman Numerals,羅馬數字的轉換

此題如果給你一串羅馬數字,請你轉成十進位的數字;如果給你十進位數字,就要轉成羅馬數字。但數字不會超過 4000,而羅馬數字最大也不過是 4000。

而羅馬數字代表為下表:
LetterIVXLCDM
Value1510501005001000

這題要注意的就是有 4 與 9 數字,如果有這種情況,要先處理。
讀入字串後只需判斷第一字是否為英文字母,如果是,則是要將羅馬數字轉十進位數字;反之,則顛倒。
我判斷的方法是屬大到小慢慢累加的方法,如果第一個字母為 M,則判斷後三個字母是否都為 M,如果是就累加 4000,再把索引移到後三個字母索引的位置,如果只有後兩個為 M,就加 2000,以此類推。再判斷 C 字母時,要先判斷後一個字母是否為 M 或 D,如果是 M,就加 900;如果是 D,就加 400,如果都不是,再判斷後兩個是否都為 C,如果是,就加 300,如果只後一字母為 C,就加 200,如果啥都沒有,就加 100。
上面看不懂沒關係,提供 C 語言程式碼最實在( 只提供 M、D、C,剩下交給大家完成 ):
sum = 0;
for (i = 0; str[i]; i ++)
{
if (str[i] == 'M')
{
if (str[i + 3] == 'M' && str[i + 2] == 'M' && str[i + 1] == 'M')
{ sum += 4000; i += 3; continue; }
if (str[i + 2] == 'M' && str[i + 1] == 'M')
{ sum += 3000; i += 2; continue; }
if (str[i + 1] == 'M') { sum += 2000; i += 1; continue; }
sum += 1000; continue;
}
if (str[i] == 'D')
{
if (str[i + 3] == 'C' && str[i + 2] == 'C' && str[i + 1] == 'C')
{ sum += 800; i += 3; continue; }
if (str[i + 2] == 'C' && str[i + 1] == 'C')
{ sum += 700; i += 2; continue; }
if (str[i + 1] == 'C') { sum += 600; i += 1; continue; }
sum += 500; continue;
}
if (str[i] == 'C')
{
if (str[i + 1] == 'M') { sum += 900; i += 1; continue; }
if (str[i + 1] == 'D') { sum += 400; i += 1; continue; }
if (str[i + 2] == 'C' && str[i + 1] == 'C')
{ sum += 300; i += 2; continue; }
if (str[i + 1] == 'C') { sum += 200; i += 1; continue; }
sum += 100; continue;
}
if (str[i] == 'L')
{
...
}
if (str[i] == 'X')
{
...
}
if (str[i] == 'V')
{
...
}
if (str[i] == 'I')
{
...
}
}
printf("%d\n", sum);

而十進位數字其實也大同小異,C 語言程式碼如下:
sscanf(str, "%d", &n);
for (;n >= 1000 && n; n -= 1000)
printf("M");
if (n / 100 == 9) printf("CM"), n -= 900;
for (;n >= 500 && n; n -= 500)
printf("D");
if (n / 100 == 4) printf("CD"), n -= 400;
for (;n >= 100 && n; n -= 100)
printf("C");

...
...
...
printf("\n");

By David.K

p11616題目連結
回ACM題庫目錄
回首頁

沒有留言: