您的位置:首页 > 其它

字典树(+DFS)——Watto and Mechanism ( CodeForces 514C )

2016-07-17 11:00 543 查看
题目链接:

http://codeforces.com/contest/514/problem/C

分析:

题目是先给出n个字符串和m个字符串,对于m个字符串中每一个字符串都可以在n个字符串中找到一个与之匹配(允许由一位字符的差异,但不允许超出或少于)。一看题目,就能想到是用n 个字符串建树,然后再搜索。

题解:

比较难写的是这个DFS函数,先讨论字符串有没有到底,到底后无错误并且之后没有节点了,就返回true,否则返回false;

然后讨论下一个字符对应的节点有没有值,有则递归判断。

最后,如果再某一个递归处发现一个错误,那么继续递归判断,然后返回结果。

DFS函数:

bool dfs(Trie *tr,int len,int f)
{
if(s[len]=='\0' )//字符串到底了
{
if(f==0 && tr->index==1)  //如果无错误且之后无节点
return true;
else
return false;
}
if(tr->next[s[len]-'a']!=0)//字符串未到底,并且字典树之后还有节点
{
if(dfs(tr->next[s[len]-'a'],len+1,f))//递归调用
return true;
}
if(f==1)//如果字符串未到底,但是字典树到底了或者不匹配并且诶错误为1,就递归调用
{
int i;
for(i=0;i<=2;i++)
if(i!=s[len]-'a' && tr->next[i]!=0)
if(dfs(tr->next[i],len+1,0))
return true;
}
return false;
}


代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
int T,t,n,m;
char s[1000010];
struct Trie
{
int index;
Trie *next[3];
Trie()
{
index=-1;
memset(next,0,sizeof(next));
}
};
Trie *root=new Trie;
void Trie_Insert(Trie *tr,int len)
{
if(s[len]!='\0')
{
if(tr->next[s[len]-'a']==0)
tr->next[s[len]-'a']=new Trie;
Trie_Insert(tr->next[s[len]-'a'],len+1);
}
else
tr->index=1;   //表示这之后没有节点
}
bool dfs(Trie *tr,int len,int f)
{
if(s[len]=='\0' )
{
if(f==0 && tr->index==1)  //如果无错误且之后无节点
return true;
else
return false;
}
if(tr->next[s[len]-'a']!=0)
{
if(dfs(tr->next[s[len]-'a'],len+1,f))
return true;
}
if(f==1)
{
int i;
for(i=0;i<=2;i++)
if(i!=s[len]-'a' && tr->next[i]!=0)
if(dfs(tr->next[i],len+1,0))
return true;
}
return false;
}
int main()
{
int i,j,k;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
{
scanf("%s",s+1);
Trie_Insert(root,1);
}
for(i=1;i<=m;i++)
{
scanf("%s",s+1);
if(dfs(root,1,1))
printf("YES\n");
else
printf("NO\n");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息