富豪凯匹配串
https://ac.nowcoder.com/acm/contest/1114/C
简单题意
有n个长度为m的文本串,每个串只含有'0'和'1'。接下来有Q次询问,每次给出一个长度为m的字符串,且只含有'0','1'和'_'。如10_1_1。下划线可以匹配'0'或'1'。即10_1_1可以匹配101111,101101,100111,100101四种串。每次询问求出n个文本串中有多少个可以与当前询问的串匹配。
正解思路
我们利用&的性质:0&1=0,0&0=0,1&0=0,1&1=1
我们发现对于每一个查询str可以把第i位:_ 看成0(把str转化为s),s[i]&a[i]的匹配目标为t[i],t[i]=0
str可以把第i位:1看成1(把str转化为s),s[i]&a[i]的匹配目标为t[i],t[i]=1
str可以把第i位:0看成1(把str转化为s),s[i]&a[i]的匹配目标为t[i],t[i]=0
代码:
#include <bits/stdc++.h>
using namespace std;
#define N 10000+5
typedef long long ll;
bitset<N> a[N],s,t;
char str[N];
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%s",str);
for(int j=0;j<m;j++)
{
a[i][j]=str[j]-'0';
}
}
int q;
scanf("%d",&q);
for(int i=1;i<=q;i++)
{
scanf("%s",str);
for(int j=0;j<m;j++)
{
if(str[j]=='_')
{
s[j]=0;
t[j]=0;
}
else
{
s[j]=1;
t[j]=str[j]-'0';
}
}
int ans=0;
for(int j=1;j<=n;j++)
{
if((a[j]&s)==t)
ans++;
}
printf("%d\n",ans);
}
return 0;
}