方法大概是把病毒的模板片段建一个图,让每个 RNA 在上边跑,跑到终点就是存在。
#include<bits/stdc++.h>
#define LL long long
#define mkp(x,y) make_pair(x,y)
#define CLR(a,x) memset(a,x,sizeof(a))
//#define int long long
//#define int __int128
using namespace std;
const int N = 2e5 + 5;
const int M = 1e6 + 5;
const int I_INF = 2e9 + 5;
const LL L_INF = 2e18 + 5;
string t;
int n, mp[205], tot, ans;
void init() {
memset(mp,-1,sizeof(mp));
mp['A'] = 0;
mp['C'] = 1;
mp['T'] = 2;
mp['G'] = 3;
}
struct Node {
vector <int> nxt[4];
int end;
}tr[N];
int vis[N];
void query(string s) {
int len = s.size();
vector <int> now, p;
now.clear();
now.push_back(0);bool flg = 0;
for(int i = 0;i < len;i++) {
flg = 0; p.clear();
for(int j = 1;j <= tot;j++)vis[j] = 0;
for(auto u : now) {
for(auto v : tr[u].nxt[mp[s[i]]]) {
if(!vis[v] && v) {
vis[v] = 1;
p.push_back(v);
flg |= tr[v].end;
}
}
}
now = p;
}
ans += 1 - flg;
}
int main() {
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
ios :: sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin >> t >> n;
int len = t.size();
init();
for(int i = 0;i < len;i++) {
if(mp[t[i]] != -1) {
tr[tot].nxt[mp[t[i]]].push_back(tot + 1);
tot++;
}
else if(t[i] == '?') {
for(int j = 0;j < 4;j++)
tr[tot].nxt[j].push_back(tot + 1);
tot++;
}
else if(t[i] == '*') {
for(int j = 0;j < 4;j++)
tr[tot].nxt[j].push_back(tot);
}
}
tr[tot].end = 1;
for(int i = 1;i <= n;i++) {
string s;
cin >> s;
query(s);
}
cout << ans << endl;
return 0;
}