1. 程式人生 > 實用技巧 >POJ 2503 Babelfish (詞典)

POJ 2503 Babelfish (詞典)

這道題用的詞典來解的,應該也可以用Trie樹(但是我暫時不會):

詞典就是一個鍵值Key,和一個對應的值Value

前往題目:POJ 2503

Describe:
You have just moved from Waterloo to a big city. The people here speak an incomprehensible dialect of a foreign language. Fortunately, you have a dictionary to help you understand them.
Input:
Input consists of up to 100,000 dictionary entries, followed by a blank line, followed by a message of up to 100,000 words. Each dictionary entry is a line containing an English word, followed by a space and a foreign language word. No foreign word appears more than once in the dictionary. The message is a sequence of words in the foreign language, one word on each line. Each word in the input is a sequence of at most 10 lowercase letters.
Output:
Output is the message translated to English, one word per line. Foreign words not in the dictionary should be translated as "eh".
Sample Input:
dog ogday
cat atcay
pig igpay
froot ootfray
loops oopslay

atcay
ittenkay
oopslay
Sample Output:
cat
eh
loops

題目大意:

題意很好理解,就是給一堆英文單詞和與之對應的火星文,然後給若干個火星文,如果詞典裡有對應的英文單詞,則輸出,否則輸出“eh”。

解題思路:

構造一個詞典即可,但是因為此題資料量較大,除了用printf和scanf以外,在查詢的時候還需要用二分查詢,將複雜度降到O(log n),不然會T吧。

AC程式碼:

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <algorithm>
 5 #define N 100000 // 最大詞典數
 6 using namespace std;
 7 struct node
 8 {
 9     char w[100];
10     char
e[100]; 11 } s[N]; // 用結構體構造的詞典,我想到的最簡單的方法就是用結構體了,其他的更好的還沒想到 12 bool cmp(struct node a, struct node b) // 排序的比較函式 13 { 14 return strcmp(a.w,b.w)>=0?1:0; // 注意這裡,除0以外所有數都是true WA了一次 15 } 16 int main() 17 { 18 int i = 0; // 輸入詞典的計數器 19 int f = 1; // 判斷能否找到的標誌 20 char c,tmp[100]; // c是判斷當前讀入的是詞典還是一個詢問,tmp為中間字串變數 21 while(~scanf("%s",s[i].e)) 22 { 23 c = getchar(); // 如果為換行,說明是個詢問 24 if(c == '\n') 25 { 26 strcpy(tmp,s[i].e); // 不要忘了將字串複製給tmp 27 break; 28 } 29 if(c == ' ') scanf("%s",s[i].w); // 如果是空格,說明是個詞典 30 i++; 31 } 32 sort(s,s+i,cmp); // 詞典按字典序降序排列 33 do 34 { 35 // 初始變數的各種初始化 36 f = 1; 37 int l = 0, r = i-1, mid,t; 38 mid = (r-l)/2+l; 39 t = strcmp(s[mid].w,tmp); 40 while(t != 0) 41 { 42 if(r-l == 1) // 這個 43 { 44 if(strcmp(s[l].w,tmp) == 0) mid = l; 45 else if(strcmp(s[r].w,tmp) == 0) mid = r; 46 else f = 0; 47 break; 48 } 49 if(r == l) // 還有這個,都是在臨界點的特判 50 { 51 if(strcmp(s[r].w,tmp) != 0) 52 f = 0; 53 else mid = r; 54 break; 55 } 56 if(r < l) {f = 0; break;} // 有備無患,小的話直接break 57 if(t > 0) // 常規二分 58 { 59 l = mid; 60 mid = (r-l)/2+l; 61 } else { 62 r = mid; 63 mid = (r-l)/2+l; 64 } 65 t = strcmp(s[mid].w,tmp); 66 } 67 if(f) printf("%s\n",s[mid].e); // 按要求輸出 68 else printf("eh\n"); 69 }while(~scanf("%s",tmp)); 70 return 0; 71 }

小結:

終於學會了詞典,那個電話聊天狂人那道題應該也可以這麼做吧,挺好的方法。

更新:

靈光一閃,弄兩個陣列,一個詞典陣列,詞典數組裡面存地址,地址對應就是火星文那個陣列,應該也可以。