题目描述
有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;
}