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
思路
給定很多單詞,問是否存在一個單詞是由給定的兩個單詞組成的。首先對給定的單詞建立一棵字典樹,給單詞末尾標記一下,然後暴力枚舉每個單詞的左半邊和右半邊。如果兩邊都能找到說明這個單詞是可以由兩個單詞組合而成,還是挺簡單的一道題。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn = 100005;
int trie[maxn][26];
char str[50005][40];
bool f[maxn];
int cnt = 0;
void insert_s(char *s)
{
int root = 0;
int n = strlen(s);
for(int i = 0;i < n;i++){
int k = s[i] - 'a';
if(!trie[root][k]){
trie[root][k] = ++cnt;
}
root = trie[root][k];
}
f[root] = true;
}
bool find_s(char *s,int x,int y)
{
int root = 0;
for(int i = x;i < y;i++){
int k = s[i] - 'a';
if(!trie[root][k]){
return false;
}
root = trie[root][k];
}
return f[root];
}
int main()
{
memset(trie,0,sizeof(trie));
memset(f,false,sizeof(f));
int n = 0;cnt = 0;
while(~scanf("%s",str[n])){
insert_s(str[n]);n++;
}
for(int i = 0;i < n;i++){
int len = strlen(str[i]);
int ans = 0;
for(int j = 1;j < len;j++){
bool a = find_s(str[i],0,j);
bool b = find_s(str[i],j,len);
if(a && b){
ans = 1;
break;
}
}
if(ans == 1) printf("%s\n",str[i]);
}
return 0;
}
願你走出半生,歸來仍是少年~