牛客练习赛53 C. 富豪凯匹配串 (bitset 优化 + 位运算)

C. 富豪凯匹配串

题目

给出 n 个长度为 m 的 01 串,有 q 次询问,每次给出一个长度 m 的字符串(只有 0,1,_),问之前 n 个串有多少可以匹配?( _ 可以匹配 0 或者 1)
n, m <1e3, q < 3e3

分析

考虑每次都把 n 遍历完(Onmq)肯定会超时。因此要优化每次的匹配过程。

这里用两个数组,ones[i][[j] 如果为 1,表示第 j 个串的 i 位置为 1。也就是说,如果想知道 i 位置有 0到n 的哪些串是 1,就看一下 ones[i] 这个数组即可。zeros 同理

做法:遍历 m 位置,ans[i] 存还有多少满足要求,每次迭代从 ans 种选出满足当前位置要求的,最后剩下来就是满足所有位置要求的。( 利用位运算 & 可以将每次 n 的遍历优化到 O1。)

代码

#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define ll long long
#define fuck(x) cout<<x<<endl
const int N = 1e3 + 10;
const ll mod = 1e9 + 7;

int n, m, q;
char str[N][N], c[N];
bitset<N> ans, ones[N], zeros[N];  //ones[i] 表示 i 位置是 1 的下标

int main(){
	scanf("%d%d", &n, &m);
	for(int i = 0; i < n; i++){
		scanf("%s", str[i]);
		for(int j = 0; j < m; j++){
			if(str[i][j] == '1')
				ones[j][i] = 1;
			else
				zeros[j][i] = 1;
		}
	}
	scanf("%d", &q);
	while(q--){
		scanf("%s", c);
		ans.set();		// ans[i] 为 1 表示 i 号串满足要求
		for(int i = 0; i < m; i++){
			if(c[i] == '1')
				ans &= ones[i];
			if(c[i] == '0')
				ans &= zeros[i];
		}
		printf("%d\n", ans.count());	// 数下有多少满足要求
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值