题意:给你n个单词(n<=5e4),让你找出能由其他两个单词拼成的单词。
思路:对于每个单词去枚举分割点,找一下拆成的两个单词是否都存在即可。
这题坑点比较多:
1.读入时不能用gets()!=NULL, 要用scanf()!=EOF
2.找到正确的分割点输出单词后记得要break,否则可能多次输出。
3.自己想简单了,Match时不是光val==1就行了,忘记考虑ch[][]不存在时也要返回false。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxnode = 50000*27+5;
int ch[maxnode][27], val[maxnode], sz;
char str[50005][27];
void init()
{
sz = 1;
memset(ch[0], 0, sizeof(ch[0]));
}
void Insert(char *s)
{
int u = 0;
int len = strlen(s);
for(int i = 0; i < len; i++)
{
if(ch[u][s[i]-'a'] == 0)
{
memset(ch[sz], 0, sizeof(ch[sz]));
val[sz] = 0;
ch[u][s[i]-'a'] = sz++;
}
u = ch[u][s[i]-'a'];
}
val[u] = 1;
}
bool Match(char *s)
{
int u = 0;
int len = strlen(s);
for(int i = 0; i < len; i++)
{
if(ch[u][s[i]-'a'] == 0) return 0;
u = ch[u][s[i]-'a'];
}
return val[u]==1;
}
int main(void)
{
int cnt = 0;
init();
while(scanf("%s",str[cnt])!=EOF)
{
Insert(str[cnt]);
cnt++;
}
for(int i = 0; i < cnt; i++)
{
int len = strlen(str[i]);
for(int k = 0; k < len-1; k++)
{
char str1[27], str2[27];
for(int j = 0; j <= k; j++)
str1[j] = str[i][j];
str1[k+1] = 0;
for(int j = k+1; j < len; j++)
str2[j-k-1] = str[i][j];
str2[len-k-1] = 0;
if(Match(str1) && Match(str2))
{
puts(str[i]);
break;
}
}
}
return 0;
}