a ahat hat hatword hziee word
ahat hatword
题意:给你一个字典,问里面那些单词可以由两个字典中单词拼接而成。
PS:我开始理解的题目是单词是要以两个出现过的单词拼接起来才算是hat's word,比如a,a,aa,aa=a+a,如果是a,aa就不行了。
但是最后发现只要是出现过的就行了,数目无所谓,而且单词相同也可以(那two other words是什么意思啊)
题解:字典树,发现有匹配的前缀再去判断剩下的一段是不是有匹配就行了。
#include<cstdio> #include<string> #include<vector> #include<cstring> #include<algorithm> using namespace std; struct node { node *next[26]; int id,num; node() { memset(next,0,sizeof(next)); id=0; num=0; } }*head; char s[50005]; vector<string> mat,out; void build(char *s,node *head,int id) { int len=strlen(s),k; for(int i=0; i<len; ++i) { k=s[i]-'a'; if(head->next[k]==NULL) head->next[k]=new node(); head=head->next[k]; } head->id=id; head->num++; } bool bfs(char *s,node *head) { int len=strlen(s),j,k,h; node *p=head,*q; for(int i=0; i<len; ++i,p=p->next[k]) { k=s[i]-'a'; if(p->next[k]==NULL) return false; if(p->next[k]->id) { q=head; for(j=i+1; j<len; ++j,q=q->next[h]) { h=s[j]-'a'; if(q->next[h]==NULL) break; } if(j==len&&q->id) //if((q->id!=p->next[k]->id)||(q->num>1)) return true; } } return false; } int main() { head=new node(); for(int i=1; ~scanf("%s",s); ++i) { build(s,head,i); mat.push_back(string(s)); } for(int i=0; i<mat.size(); ++i) { strcpy(s,mat[i].c_str()); if(bfs(s,head)) out.push_back(mat[i]); } sort(out.begin(),out.end()); for(int i=0; i<out.size(); ++i) printf("%s\n",out[i].c_str()); return 0; }