问题传送门
有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__匹配

分析
多次查询问题,一般是多查询过程比较耗时,本题中如果逐一字符比较一定会超时。利用bitset可减少,利用bitset位运算可直接比较字符串,bitset在一些情况时很好用,bitset可以看做一种特殊的数组。

			if(s[i]=='_')
				q[i]=p[i]=0;
			else
			{
				q[i]=1,p[i]=s[i]=='1'?1:0;
			}

这一部分是代码的主要部分,可以用例子模拟一下

#include<stdio.h>
#include<iostream>
#include<string>
#include<bitset>
using namespace std;
const int maxn=1e3+10;
bitset<maxn> b[maxn],p,q;
char s[maxn];
int main()
{
	int n,m;
	int x;
	scanf("%d%d",&n,&m);
	for(int i=0;i<n;i++)
	{
		scanf("%s",s);
		for(int j=0;j<m;j++)
		{
			if(s[j]=='1')
				b[i][j]=1;
			else
				b[i][j]=0;
		}
		
	}
	scanf("%d",&x);
	while(x--)
	{
		int ans=0;
		scanf("%s",s);
		for(int i=0;i<m;i++)
		{
			if(s[i]=='_')
				q[i]=p[i]=0;
			else
			{
				q[i]=1,p[i]=s[i]=='1'?1:0;
			}
			
		}
		for(int i=0;i<n;i++)
		{
			if((b[i]&q)==p)
				ans++;
		}
		printf("%d\n",ans);
	}
	return 0;
}