给出一个词典,找出所有的复合词,即恰好有两个单词连接而成的单词。输入每行都是
一个由小写字母组成的单词。输入已按照字典序从小到大排序,且不超过120000个单词。输
出所有复合词,按照字典序从小到大排列。
题目很好 理解 用好久没字典树了,写了很多坑
要注意:
自己和自己也可以组成一个
比如 a aa aa是可以输出的
#pragma GCC optimize(2)
#include <bits/stdc++.h>
using namespace std;
#define S s[i] - 'a'
#define mem(a,b) memset(a,b,sizeof(a))
const int maxd = 120005;
struct node
{
bool is_word;
node *next[26];
node():is_word(false) {
for(int i = 0;i<26;i++)
{
this->next[i] = NULL;
}
}
};
void ins(node *Root,char *s)
{
node *p = Root;
int i = 0;
for(;s[i];i++)
{
if(p->next[S] == NULL)
{
p->next[S] = new node();
}
p = p->next[S];
// printf("%c",s[i]);
}
p->is_word = true;
// printf("\n");
}
bool find_is(node *Root ,char *s)
{
node *p = Root;
int i,top=0;
stack<int>v;
for(int i = 0;s[i]!='\0';i++)
{
if(p->is_word)v.push(i);
p = p->next[S];
}
while(!v.empty())
{
int i = v.top();
p = Root;
v.pop();
for(;s[i]!='\0'&&p;i++)
{
p = p->next[S];
}
if(s[i] == '\0'&&p&&p->is_word)return true;
}
return false;
}
char word[maxd][30];
int main(void)
{
// freopen("input.in","r",stdin);
// freopen("output.out","w",stdout);
node *root = new node();
register int cnt = 0;
while(scanf("%s",word[cnt])!=EOF)
ins(root,word[cnt++]);
for(int i = 0;i<cnt;i++)
{
if(find_is(root,word[i]))
{
puts(word[i]);
}
}
}
vj上偷的最短AC代码 开o2优化应该也是 0ms 0k