题目描述
有n个长度为m的文本串,每个串只含有’0’和’1’。接下来有Q次询问,每次给出一个长度为m的字符串,且只含有’0’,‘1’和’’。如10_1_1。下划线可以匹配’0’或’1’。即10_1_1可以匹配101111,101101,100111,100101四种串。每次询问求出n个文本串中有多少个可以与当前询问的串匹配。
输入描述:
第一行输入n,m
接下来n行,每行输入一个长度为m的01串表示一个文本串。
第n+2行输入Q
接下来Q行,每行输入一个长度为m的字符串(只包含’0’,‘1’,’’)。
1<=n,m<=1000,1<=Q<=3000。
输出描述:
对于每次询问,输出n个文本串中有多少个与当前询问的串匹配。
示例1
输入
复制
5 6
101101
011011
100110
111000
101111
2
1011_1
1__1__
输出
复制
2
3
说明
第一次询问:有101101,101111与1011_1匹配
第二次询问:有101101, 100110, 101111与1__1__匹配
因为字符只有0和1,故我们可以直接用bitset压位。
然后我们怎么模糊匹配呢?就用bitset的与运算即可,就是我们用一个bitset的1表示当前这一位是我们需要匹配的,然后如果为’_'我们就为0,代表不需要匹配,因为与之后就没了,然后我们直接暴力匹配每一个即可。
AC代码:
#pragma GCC optimize(2)
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=1010;
int n,m,q;
bitset<N> bs[N],t,a,b;
char str[N];
signed main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
scanf("%s",str+1);
for(int j=1;j<=m;j++) bs[i][j]=str[j]-'0';
}
cin>>q;
while(q--){
int res=0;
scanf("%s",str+1);
for(int j=1;j<=m;j++){
if(str[j]=='_'){
a[j]=0; b[j]=0;
}else{
a[j]=1; b[j]=str[j]-'0';
}
}
for(int i=1;i<=n;i++){
t=bs[i]&a;
if(t==b) res++;
}
printf("%d\n",res);
}
return 0;
}