試題 算法提高 P1003
時間限制:1.0s 內存限制:256.0MB
作爲一名網絡警察,你的任務是監視電子郵件,看其中是否有一些敏感的關鍵詞。不過,有些狡猾的犯罪嫌疑人會改變某些單詞的字母順序,以逃避檢查。請編寫一個程序,發現這種調整過順序的關鍵詞。程序的輸入有兩行,第一行是關鍵詞列表,第二行是待檢查的句子。程序的輸出爲在該句子中所找到的經過順序調整的關鍵詞。(單詞全部爲小寫,單詞之間以一個空格分隔,每一行的單詞個數不限)
輸入:
guns mines missiles
aameric ssell snug dan iimsssle ot sit neeemis
輸出:
guns missiles
題解
可以把每一個單詞按照升序排列存儲,這樣如果單詞是亂序的話,經過一輪sort就正序了,這時候只要查找原單詞裏面有沒有這個單詞即可。輸出的時候要求按照原來的順序輸出單詞,所以定義一個結構體 word ,裏面記錄了單詞原序和經過升序排列過的的字符串。
PS. 題目沒有明說,但是輸出也是要按原來正序的單詞的字典序輸出,所以要用到優先隊列。
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
struct word {
char a[26], b[26];
word(char _a[26], char _b[26]) {
memcpy(a, _a, 26);
memcpy(b, _b, 26);
}
};
vector<word> myset;
struct cmp {
bool operator()(char *a, char *b) {
if (strcmp(a, b) >= 1)
return true;
else
return false;
}
};
priority_queue<char*,vector<char*>,cmp > Q; //注意優先隊列要重載運算符
int main() {
char a[26],b[26];
while (scanf("%s", a)) {
memcpy(b, a, strlen(a)+1);
sort(a, a + strlen(a));
myset.push_back(word(b, a));
if (getchar() == '\n')
break;
}
while (scanf("%s", a)) {
sort(a, a + strlen(a));
for (int i = 0; i < myset.size(); i++) {
if (strcmp(a, myset[i].b) == 0) {
Q.push(myset[i].a);
}
}
if (getchar() == '\n')
break;
}
while (!Q.empty()) { //每次取出字典序最小的單詞
fputs(Q.top(),stdout);
printf(" ");
Q.pop();
}
return 0;
}