题意:输入a个字符串和b个待检测字符串。问待检测字符串是否可以由某个已知字符串改变且只改变一个字母得到。
分析:字符串hash,枚举待测字符串每一位进行修改,看是否符合,好像正解是trie树。
#include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #define N 600010 #define LL long long using namespace std; const int HASH=1000007; const int MAXN=500010; const LL MOD=10000000000007ll; struct HASHMAP { int head[HASH],next[MAXN],size; LL state[MAXN]; void init() { size=0; memset(head,-1,sizeof(head)); } bool find(LL val) { int h=val%HASH; for(int i=head[h];~i;i=next[i]) { if(val==state[i])return true; } return false; } int insert(LL val) { int h=val%HASH; for(int i=head[h];~i;i=next[i]) { if(val==state[i]) return 0; } state[size]=val; next[size]=head[h]; head[h]=size++; return 1; } }H; LL p[N]; const LL SEED=113; char s[N]; int main() { int n,m; scanf("%d%d",&n,&m); p[0]=1ll; for(int i=1;i<N;i++)p[i]=p[i-1]*SEED%MOD; H.init(); for(int i=1;i<=n;i++) { scanf("%s",s); int len=strlen(s); LL val=0; for(int j=0;j<len;j++)val=(val*SEED+s[j])%MOD; H.insert(val); } for(int i=1;i<=m;i++) { scanf("%s",s); int len=strlen(s); LL val=0; for(int j=0;j<len;j++)val=(val*SEED+s[j])%MOD; bool flag=false; for(int j=0;j<len&&!flag;j++) { LL tmp=p[len-1-j]*s[j]%MOD; LL cnt=((val-tmp)%MOD+MOD)%MOD; for(int k=0;k<3;k++) { if(k+'a'!=s[j]) { LL nh=p[len-1-j]*(k+'a')%MOD; if(H.find((cnt+nh)%MOD)) { flag=true; break; } } } } if(flag)puts("YES"); else puts("NO"); } }