思路:由于字符串长度上限为6*10^5,直接比较十分耗时。而只有a,b,c三种字符,所以使用trie查找相差一位的字符串。
给定字符串s,到达trie上某一个Node时,s[i]可以选择改或者不改,而更改与否影响到了后续的处理,所以在trie上dfs即可。
代码如下:
#include <cstdio>
#include <cstring>
using namespace std;
#define N 600005
struct Node{
bool fin;
Node* next[3];
Node(): fin(false) {
for(int i = 0; i < 3; ++i)
next[i] = 0;
}
};
char s[N];
Node* root = 0;
void insert(const char* str){
if(!root)
root = new Node();
Node* cur = root;
while(*str){
int idx = *str - 'a';
if(!cur->next[idx]){
Node* next = new Node();
cur->next[idx] = next;
}
++str;
cur = cur->next[idx];
}
cur->fin = true;
}
bool query(const Node* pos, const char* str, bool diff){
if((*str) == 0){
if(pos->fin && diff)
return true;
return false;
}
const Node* cur = pos;
if(diff){
while(*str){
int idx = *str - 'a';
if(!cur->next[idx])
return false;
++str;
cur = cur->next[idx];
}
return cur->fin;
}
else{
int idx = *str - 'a';
const char* next_char = ++str;
for(int i = 0; i < 3; ++i){
Node* tmp = cur->next[i];
if(!tmp)
continue;
if(query(tmp, next_char, !(i == idx)))
return true;
}
return false;
}
}
int main(){
int n, m;
scanf("%d %d", &n, &m);
for(int i = 0; i < n; ++i)
scanf("%s", s), insert(s);
for(int i = 0; i < m; ++i){
scanf("%s", s);
if(query(root, s, false))
printf("YES\n");
else
printf("NO\n");
}
return 0;
}