富豪凯匹配串

问题传送门
有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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chp的博客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值