Description
给出 (n) 个已知字符串,(m) 次询问,每次询问给出一个字符串,问上面 (n) 个字符串中是否有一个字符串满足恰好有一个字母不同于询问的字符串。字符串的字符集为 {a,b,c}
。
Solution
对于每个已知字符串,我们可以将它的 hash 值扔进一个集合里。
对于每个询问串,我们枚举修改哪一个字符,以及修改成什么。
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6 + 5;
const int mod = 1e11 + 7;
const int bas = 137;
int n, m;
string src[N], query[N];
int pwr[N];
int clamp(int x)
{
return (x % mod + mod) % mod;
}
int gethash(string s)
{
int ans = 0;
for (int i = 0; i < s.length(); i++)
{
ans += s[i] * pwr[i];
ans %= mod;
}
return ans;
}
signed main()
{
ios::sync_with_stdio(false);
cin >> n >> m;
for (int i = 1; i <= n; i++)
cin >> src[i];
for (int i = 1; i <= m; i++)
cin >> query[i];
pwr[0] = 1;
for (int i = 1; i < N; i++)
pwr[i] = pwr[i - 1] * bas % mod;
set<int> s;
for (int i = 1; i <= n; i++)
{
int hashval = gethash(src[i]);
s.insert(hashval);
}
for (int i = 1; i <= m; i++)
{
int origin_hashval = gethash(query[i]);
vector<int> modified_hashval;
string &str = query[i];
int len = str.length();
for (int j = 0; j < len; j++)
{
char ch = str[j];
if (ch == 'a')
{
modified_hashval.push_back(clamp(origin_hashval + pwr[j]));
modified_hashval.push_back(clamp(origin_hashval + pwr[j] * 2));
}
if (ch == 'b')
{
modified_hashval.push_back(clamp(origin_hashval + pwr[j]));
modified_hashval.push_back(clamp(origin_hashval - pwr[j]));
}
if (ch == 'c')
{
modified_hashval.push_back(clamp(origin_hashval - pwr[j]));
modified_hashval.push_back(clamp(origin_hashval - pwr[j] * 2));
}
}
int flag = 0;
for (auto val : modified_hashval)
{
if (s.find(val) != s.end())
{
flag = 1;
break;
}
}
cout << (flag ? "YES" : "NO") << endl;
}
}