这道题是有问题的,一个单词是可以被另外一个单词拼接两次得到的,如ab,abab,输出是abab,然而原题确指明,某个单词当且仅当是另外字典里的两个单词拼接的,才是一个hat’s word,实际上这道题出的不严谨,因为这个问题WA了十几次。
代码如下:
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
const int maxn=2e5+5e4+5;
int Trie[maxn][26];
int num[maxn];
char s[50005][105];
int tot=1;
void insert(char *str)
{
int len,node,i;
len=strlen(str)-1;
node=0;
for(i=0;i<=len;i++)
{
if(Trie[node][str[i]-'a']==0)
Trie[node][str[i]-'a']=tot++;
node=Trie[node][str[i]-'a'];
}
num[node]++;
}
int inquire1(char *str) //查看某个单词的后半部分是否有在字典树里面
{
int len,i,node;
node=0;
len=strlen(str)-1;
for(i=0;i<=len;i++)
{
if(Trie[node][str[i]-'a']==0)
return 0;
node=Trie[node][str[i]-'a'];
}
return num[node];
}
void inquire2(char *str) //读取单词
{
int len,flag,node,i,j;
char s0[30];
len=strlen(str)-1;
node=flag=0;
for(i=0;i<=len;i++)
{
if(flag) //flag=1时,开始复制该单词后面的部分,然后进行查看
{
for(j=i;j<=len;j++)
s0[j-i]=str[j];
s0[j-i]='\0';
if(inquire1(s0))
{
printf("%s\n",str);
break; //是hat's word,输出后就可以结束了,避免反复输出同一个单词
}
flag=0;
}
node=Trie[node][str[i]-'a'];
if(num[node]>=1&&i!=len) //如果发现另外一个单词是该单词的子串(不包含它自己),则flag=1
flag=1;
}
}
int main()
{
memset(Trie,0,sizeof(Trie));
memset(num,0,sizeof(num));
int i,j,k;
i=0;
while(~scanf("%s",s[i]))
{
insert(s[i++]);
}
j=0;
while(j<i)
{
inquire2(s[j++]);
}
return 0;
}