題目: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(<),隨后 N 行,每行給出一個 [0, 169) 區間內的數字 —— 或者是地球文,或者是火星文。
輸出格式:
對應輸入的每一行,在一行中輸出翻譯后的另一種語言的數字。
輸入樣例:
4 29 5 elo nov tam
輸出樣例:
hel mar may 115 13
思路:
- 地球數字對應的火星文開數組對應下標進行利用
- 判斷是地球文還是火星文。可以根據第一位字符判斷,如果是數字字符那就是數字字符串的地球文,否則就是火星文。或者用C++函數庫中cctype頭文件中包含的isdigit()函數判斷是不是十進制的字符。
- 若是地球文則要將字符類型轉換為整型int,可以用stoi()函數,也可以用stringstream類型,但據說stoi不是一個函數庫,最好少用。
注意:如果是0, 輸出tret好像會自動換行,不知道為什么,應該是我的代碼的問題,看別人的好像都不會。這個點是在測試點1,我格式錯誤了,所以就直接特判了。
注意13開始就是高位數了! - 若是火星文,憑借有無空格區分兩個火星數字,然后將得到的數字進行進制轉換。
代碼:
1 #include <cstdio> 2 #include <cstring> 3 #include <cctype> //isdigit() 4 #include <iostream> 5 #include <sstream> //包含stringstream 6 #include <cmath> 7 #include <algorithm> 8 #include <string> //stoi() 9 #include <stack> 10 #include <queue> 11 #include <vector> 12 #include <map> 13 using namespace std; 14 15 int main() 16 { 17 int n; 18 char low[13][5]={"tret","jan","feb","mar","apr","may","jun","jly","aug","sep","oct","nov","dec"}; 19 char high[13][5]={"","tam","hel","maa","huh","tou","kes","hei","elo","syy","lok","mer","jou"}; 20 scanf("%d", &n); 21 string s; 22 getchar(); //后面使用getline()需要在這里接收輸入的回車, 否則會出錯 23 for(int i = 0; i < n; i++) 24 { 25 getline(cin, s); 26 if(s[0] >= '0' && s[0] <= '9') //地球文-->火星文 27 { 28 int num; 29 stringstream ss; 30 ss << s; 31 ss >> num; //將num轉為int類型 32 int flag = 0; 33 if(num == 0) 34 printf("tret"); 35 if(num < 13 && num > 0) 36 printf("%s\n", low[num]); 37 if(num >= 13) //如果數字大於等於13就需要輸出高位 38 { 39 printf("%s", high[num/13]); 40 flag = 1; 41 } 42 if(num%13 == 0) //我不加這個if語句進行處理且num會被13整除的話,在輸出高位后,后面又會多出個其他字符,導致答案錯誤,測試點在2、4 43 { 44 printf("\n"); 45 continue; 46 } 47 if(flag && num%13 != 0) 48 { 49 printf(" %s\n", low[num%13]); //在有高位的情況下,低位為零不輸出 50 } 51 } 52 else //火星文-->地球文 53 { 54 string s1 = "", s2 = ""; 55 int m = 0, k = 0; 56 for(int i = 0; i < s.length(); i++) 57 { 58 if(s[i] != ' ') //以空格為分界線區分兩個字符串 59 s1 += s[i]; 60 else 61 { 62 s2 = s1; //s2是高位 63 s1 = ""; 64 } 65 } 66 for(int i = 0; i < 13; i++) //因為可能沒有空格,所以s1可能為高位也可能為低位 67 { 68 if(s1 == low[i]) 69 m = i; 70 if(s1 == high[i]) 71 k = i; 72 if(s2 == high[i]) 73 k=i; 74 } 75 printf("%d\n", k*13+m); 76 } 77 } 78 return 0; 79 }
總結:
oj過題兩種方式:一、知道測試點數據利用特判過;二、完美的AC代碼,靠硬實力敲。前面那種方式類似投機取巧。
最初不是用空格區分兩個火星數字,代碼就搞不好,在帶有空格的字符串中可以利用空格來判斷是否開始新的單詞。學C的時候課本上有過這樣的例子,只能怪自己大一上不好好敲代碼以及不做任何總結。
有時雖然有思路,但是代碼卻不能很好實現,或者比較冗長,就是代碼敲的少的問題,功底薄弱。利用STL容器和各函數庫可以使代碼簡便很多,所以總結除了題解,還應該總結下學到的STL容器和函數庫的應用。