狀態壓縮

富豪凱匹配串

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;
}

 

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