题意:只含a,b,c的n个字符串,m个查询,每个查询回答是否存在与给定字符串长度相同且仅有一个位置不同的字符串。
分析:1.用字典树存,dfs查询,记录是否有不同字符。
2.字符串哈希,如果把输入的字符串直接排序然后查询用二分查找会卡在一组很特殊的数据上,字符串哈希要避免冲突,参考了别人的代码没有冲突。
注意:STL的find和count函数不是二分查找,时间复杂度是线性时间,lower_bound和bineral_search是对数时间。
#include<iostream>
#include<string>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<iomanip>
#include<map>
#include<algorithm>
#include<queue>
#include<set>
#define inf 10000000
#define pi acos(-1.0)
#define eps 1e-8
#define seed 131
using namespace std;
typedef pair<int,int> pii;
typedef unsigned long long ULL;
typedef long long LL;
const int maxn=100005;
LL p=17;
LL mod=1000000000000007;
LL pre[600005];
int n,m;
char s[600005];
LL d[300005];
int main()
{
pre[1]=1;
for(int i=2;i<600003;i++)
{
pre[i]=pre[i-1]*p%mod;
}
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
{
scanf("%s",s);
int len=strlen(s);
LL h=0;
for(int j=0;j<len;j++)
{
h=(h+((s[j]-'a'+1)*pre[len-j]%mod))%mod;
}
d[i]=h;
}
sort(d,d+n);
for(int i=0;i<m;i++)
{
scanf("%s",s);
int len=strlen(s);
LL h=0;
for(int j=0;j<len;j++)
{
h=(h+((s[j]-'a'+1)*pre[len-j]%mod))%mod;
}
bool flag=false;
for(int j=0;j<len;j++)
{
LL newh=(h-(s[j]-'a'+1)*pre[len-j]%mod+mod)%mod;
if(s[j]=='a')
{
LL u=(newh+('b'-'a'+1)*pre[len-j]%mod)%mod;
if(*lower_bound(d,d+n,u)==u)
{
flag=true;
break;
}
u=(newh+('c'-'a'+1)*pre[len-j]%mod)%mod;
if(*lower_bound(d,d+n,u)==u)
{
flag=true;
break;
}
}
else if(s[j]=='b')
{
LL u=(newh+('a'-'a'+1)*pre[len-j]%mod)%mod;
if(*lower_bound(d,d+n,u)==u)
{
flag=true;
break;
}
u=(newh+('c'-'a'+1)*pre[len-j]%mod)%mod;
if(*lower_bound(d,d+n,u)==u)
{
flag=true;
break;
}
}
else
{
LL u=(newh+('a'-'a'+1)*pre[len-j]%mod)%mod;
if(*lower_bound(d,d+n,u)==u)
{
flag=true;
break;
}
u=(newh+('b'-'a'+1)*pre[len-j]%mod)%mod;
if(*lower_bound(d,d+n,u)==u)
{
flag=true;
break;
}
}
}
if(flag)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
#include<iostream>
#include<string>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<iomanip>
#include<map>
#include<algorithm>
#include<queue>
#include<set>
#define inf 10000000
#define pi acos(-1.0)
#define eps 1e-8
#define seed 131
using namespace std;
typedef pair<int,int> pii;
typedef unsigned long long ULL;
typedef long long LL;
const int maxn=6000005;
int n,m;
char str[600005];
int ch[maxn][3];
int val[maxn];
int sz;
int l;
int p[3][2]={{1,2},{0,2},{0,1}};
void init()
{
sz=1;
memset(ch[0],0,sizeof(ch[0]));
}
void insert(char* s,int v)
{
int u=0,len=strlen(s);
for(int i=0;i<len;i++)
{
int c=s[i]-'a';
if(ch[u][c]==0)
{
memset(ch[sz],0,sizeof(ch[sz]));
val[sz]=0;
ch[u][c]=sz++;
}
u=ch[u][c];
}
val[u]=v;
}
bool dfs(int r,int cnt,int flag);
int main()
{
init();
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
{
scanf("%s",str);
insert(str,1);
}
for(int i=0;i<m;i++)
{
scanf("%s",str);
l=strlen(str);
if(dfs(0,0,0))
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
bool dfs(int r,int cnt,int flag)
{
if(cnt==l)
{
if(val[r]==1&&flag==1)
return true;
return false;
}
if(flag)
{
if(ch[r][str[cnt]-'a']==0)
return false;
else
{
if(dfs(ch[r][str[cnt]-'a'],cnt+1,1))
return true;
}
}
else
{
int d=str[cnt]-'a';
if(ch[r][d]!=0)
{
if(dfs(ch[r][d],cnt+1,0))
return true;
}
for(int i=0;i<2;i++)
{
if(ch[r][p[d][i]]!=0)
{
if(dfs(ch[r][p[d][i]],cnt+1,1))
return true;
}
}
}
return false;
}