题目链接:
http://codeforces.com/problemset/problem/514/C
题目大意:
先输入n个字符串,然后输入m个字符串,寻找n个字符串中有没有字符串满足只有一个字母和m中字符串不同的情况,有就输出YES,否则输出NO。
题解:
将n个字符串用字典树存进去,然后利用dfs进行搜索。
这里的dfs使用bool好做一些(我一开始使用的void,WA了两次,暂时没有什么好想法,欢迎交流),dfs函数头设置一个flag代表有没有一处不同。
AC代码:
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cctype>
#include <iostream>
using namespace std;
const int maxnode = 600500;
const int sigma = 3;
int ch[maxnode][sigma],v[maxnode],sz,k;
int u;
struct trie
{
trie()
{
sz=1;
memset(v,0,sizeof v);
memset(ch[0],0,sizeof ch[0]);
}
int idx(char c)
{
return c-'a';
}
void insert(char* s)
{
int l =strlen(s);
u=0;
for(int i=0;i<l;i++)
{
int c = idx(s[i]);
if(!ch[u][c])
{
memset(ch[sz],0,sizeof ch[sz]);
ch[u][c] = sz++;
//cout << ch[u][c] <<endl;
}
u = ch[u][c];
v[u] ++;
}
}
bool dfs(char *s,int deepth, int flag)//deepth代表字符串中第deepth个字符。
{
int tmp = u;
if(s[deepth])
{
int k = idx(s[deepth]);
if(ch[u][k] != 0)
{
u = ch[u][k];
if(dfs(s, deepth+1, flag))
return true;
}
if(flag == 0)//如果上面搜了半天没有返回ture的话,就说明需要搜索的字符串此时在树中有全部相同的部分,此时需要改变搜索方向,搜索其他节点
{
for(int i = 0; i < 3; i++)
{
if(i != k && ch[tmp][i] != 0)
{
u = ch[tmp][i];
if(dfs(s, deepth+1, 1))
return true;
}
}
}
}//如果这次搜索依然没有返回ture的话,说明不满足要求,返回false
else if(flag != 0)
return true;
return false;
}
}T;
char s1[600050];
char s2[600050];
int main()
{
int nn, mm;
cin >> nn >> mm;
while(nn--)
{
cin >> s1;
T.insert(s1);
}
while(mm--)
{
cin >> s2;
u = 0;
if(T.dfs(s2,0,0))
cout << "YES" <<endl;
else
cout << "NO" <<endl;
}
return 0;
}