题意
带通配符*和?的字符串匹配
题解
f[i][j]表示s到第i个字符,t到第j个是否存在合法情况
s[i]=t[j]
f
[
i
]
[
j
]
∣
=
f
[
i
−
1
]
[
j
−
1
]
f[i][j]|=f[i-1][j-1]
f[i][j]∣=f[i−1][j−1]
s[i]=?
f
[
i
]
[
j
]
∣
=
f
[
i
−
1
]
[
j
−
1
]
f[i][j]|=f[i-1][j-1]
f[i][j]∣=f[i−1][j−1]
s[i]=*
f
[
i
]
[
j
]
∣
=
f
[
i
−
1
]
[
k
]
(
0
<
=
k
<
=
j
)
f[i][j]|=f[i-1][k] (0<=k <=j)
f[i][j]∣=f[i−1][k](0<=k<=j)
g
[
j
]
∣
=
g
[
j
−
1
]
∣
f
[
i
]
[
j
]
g[j]|=g[j-1]|f[i][j]
g[j]∣=g[j−1]∣f[i][j]
用g数组优化即可
简单题也写不对QAQ
code
#include<cstdio>
#include<algorithm>
#include<cstring>
#define fo(i,a,b) for (int (i)=(a);(i)<=(b);(i)++)
using namespace std;
const int N=1005;
const int M=505;
bool f[N][N],g[N];
char s[N],t[N];
int n,m,tot,q;
int main(){
// freopen("data.in","r",stdin)
scanf("%s",s+1);
n=strlen(s+1);
scanf("%d",&q);
tot=q;
while (q--){
memset(f,0,sizeof(f));
f[0][0]=1;
fo(i,0,m) g[i]=1;
scanf("%s",t+1);
m=strlen(t+1);
fo(i,1,n) {
fo(j,0,m) {
if (s[i]=='*') f[i][j]|=g[j];
if (!j) continue;
if (s[i]=='?') f[i][j]|=f[i-1][j-1];
if ('A'<=s[i] && s[i]<='Z' && s[i]==t[j])
f[i][j]|=f[i-1][j-1];
}
memset(g,0,sizeof(g));
g[0]=f[i][0];
fo(j,1,m) {
g[j]|=g[j-1]|f[i][j];
}
}
if (f[n][m]) tot--;
}
printf("%d",tot);
return 0;
}