Hat’s Words
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 7298 Accepted Submission(s): 2644
Problem Description A hat’s word is a word in the dictionary that is the concatenation of exactly two other words in the dictionary.
You are to find all the hat’s words in a dictionary.
Input Standard input consists of a number of lowercase words, one per line, in alphabetical order. There will be no more than 50,000 words.
Only one case.
Output Your output should contain all the hat’s words, one per line, in alphabetical order.
Sample Input
a ahat hat hatword hziee word
Sample Output
ahat hatword
Author 戴帽子的 trie树的简单应用: 题目意思为:给你一大串单词,让你输出所有的有这样性质的单词:该单词有两个单词组成,按字典序输出
做法为: 建立trie树,将每个单词插入到trie树上,然后枚举每个单词的前缀,及对应的后缀,两个单词分别到trie树查询,看是否为“真前缀”
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <string>
#include <algorithm>
#include <queue>
using namespace std;
vector<string> vs,ans;
const int maxn = 5000000;
int ch[maxn][26];
int cnt;
int val[maxn];
int idx(char a){
return a-'a';
}
void insert(string st){
int u = 0;
for(int i = 0; i < st.size(); i++){
int k = idx(st[i]);
if(!ch[u][k]){
val[cnt] = 0;
memset(ch[cnt],0,sizeof ch[cnt]);
ch[u][k] = cnt++;
}
u = ch[u][k];
}
val[u] = 1;
}
bool isprefix(string st){
int u = 0;
for(int i = 0; i < st.size(); i++){
int k = idx(st[i]);
if(!ch[u][k]) return false;
u = ch[u][k];
}
return val[u];
}
int main(){
cnt = 1;
memset(ch[0],0,sizeof ch[0]);
memset(val,0,sizeof val);
string str;
vs.clear();
ans.clear();
while(cin >> str){
insert(str);
vs.push_back(str);
}
for(int i = 0; i < vs.size(); i++){
for(int j = 0; j < vs[i].size(); j++){
string t1 = vs[i].substr(0,j+1),t2 = vs[i].substr(j+1);
//cout<<t1<<" "<<t2<<endl;
if(isprefix(t1)&&isprefix(t2)){
ans.push_back(vs[i]);
break;
}
}
}
sort(ans.begin(),ans.end());
for(int i = 0; i < ans.size(); i++){
cout<<ans[i]<<endl;
}
return 0;
}