题意:
先给n个字符串(由a,b,c组成),再给m个查询,问存不存在和n个中的某一个只差一个字符
(0 ≤ n ≤ 3·10, 0 ≤ m ≤ 3·10
)
题解:
n和m都很大
有两种做法:hash和字典树
就是很暴力的做法
把模板串整体哈希并记录值
然后依次改变目标串的每一位,改成a~c,然后查看是否存储过,没有就移动到下一位进行相同的操作
字典树
利用字典树处理前n个字符串,然后再字典树上跑dfs
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=6e5+9;
ll p[maxn];
set<ll>myset;
ll mod=1e12+7;
int main()
{
p[0]=1;
for(int i=1;i<=maxn;i++)
{
p[i]=(p[i-1]*131)%mod;
}
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
string s;
cin>>s;
ll sum=0;
int len=s.length();
for(int j=0;j<=len-1;j++)
{
sum=(sum*131+s[j]-'0')%mod;
}
myset.insert(sum);
}
for(int i=1;i<=m;i++)
{
string s;
cin>>s;
ll sum=0;
ll ans=0;
bool f=0;
int len=s.length();
for(int j=0;j<=len-1;j++)
{
sum=(sum*131+s[j]-'0')%mod;
}
for(int j=0;j<=len-1;j++)
{
if(f==1)break;
for(char x='a';x<='c';x++)
{
if(s[j]==x)continue;
ans=(sum-(s[j]-'0')*p[len-j-1])%mod;
if(ans<0)ans=(ans+mod)%mod;
ans=(ans+(x-'0')*p[len-j-1])%mod;
if(myset.count(ans))
{
f=1;
break;
}
}
}
if(f)cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}字典树
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <string>
#include <map>
#include <set>
#define LL long long
using namespace std;
#define maxn 300007
#define maxx 600007
#define maxNode 3
int num[maxn][3];
char s[maxx];
struct node
{
node* next[maxNode];
int flag;
};
node* createNode()
{
node *q=new node;
for(int i=0;i<maxNode;i++)
{
q->next[i]=NULL;
}
return q;
}
void insertNode(node *trie,char *c)
{
int i=0;
int k;
node *p=trie;
while(c[i])
{
k=c[i++]-'a';
if(p->next[k]==NULL)
{
node *q=createNode();
p->next[k]=q;
}
p=p->next[k];
}
p->flag=1;
}
int dfs(node *trie,char *c,int x)
{
node *p=trie;
int i,j;
if(trie==NULL) return 0;
if(c[0]=='\0')
{
if(x==1&&p->flag)
{
return 1;
}
else
{
return 0;
}
}
for(i=0;i<3;i++)
{
if(c[0]=='a'+i)
{
if(dfs(trie->next[i],c+1,x)) return 1;
}
else if(x==0)
{
if(dfs(trie->next[i],c+1,1)) return 1;
}
}
return 0;
}
int main()
{
int len,n,i,j,k,m,x,y;
scanf("%d%d",&n,&m);
node *trie=createNode();
for(i=1;i<=n;i++)
{
scanf("%s",s);
insertNode(trie,s);
}
for(j=1;j<=m;j++)
{
scanf("%s",s);
bool flag=0;
for(i=0;i<3;i++)
{
if(s[0]=='a'+i)
{
if(dfs(trie->next[i],s+1,0))
{
flag=1;
break;
}
}
else if(dfs(trie->next[i],s+1,1))
{
flag=1;
break;
}
}
if(flag) printf("YES\n");
else printf("NO\n");
}
return 0;
}

京公网安备 11010502036488号