牛客練習賽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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章