ZOJ 2975-K - Kinds of Fuwas-暴力+bitset

给出一个n*m的矩阵 里面有BJHYN的 五种字母,

求出所有 矩形 满足 四个角的字母 是相同的

我们发现 如果对于任意两行,满足  这两行的 第   i,j,k位置的字母都一样,则 可以得到1*2*3*....n-1个合法矩形


思路:位运算

预处理,把矩阵中为B的字母看作1,其余都是0

对于01矩阵任意两行,看成两个数,a,b  则a&B得到的就是  两行对应位置同时存在 B字母的结果

那么数出a&b 里面有几个1,则这两行形成的合法矩形就是 num*(num-1)/2个


对于任意两行来一次,  求可以求出所有的

同样的方法处理JHYN,

复杂度5*n*m*m  最后一个m是数数a&b里面有几个1的操作     


  ac 代码:

#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue>
#include <map>
#include <bitset>
#include <vector>
using namespace std;

int tm[255][255];

bitset<255> sb[255];
bitset<255> ss;
int n,m;
long long ans;
void solve(char X);
int main() 
{
	int h;
	int i,j;
	int t;
	cin>>t;
	while(t--)
	{
		
		scanf("%d%d",&n,&m);
		getchar();
		for (i=1;i<=n;i++)
		{  
			for (j=1;j<=m;j++) 
				scanf("%c",&tm[i][j]);  
			
			getchar();
		}
		
		ans=0;
		solve('B');
		solve('J');
		solve('H');
		solve('Y');
		solve('N'); 
		printf("%lld\n",ans);
	}
	
	
	return 0;
	
} 

void solve(char X)
{
	int i,j;
	for (i=1;i<=n;i++) 
		sb[i].reset(); 
	for (i=1;i<=n;i++)
	{
		for (j=1;j<=m;j++)
		{
			if (tm[i][j]==X)
				sb[i].set(j); 
		}
	}
	
	for (i=1;i<=n;i++)
	{
		for (j=i+1;j<=n;j++)
		{
			ss=sb[i];
			//		cout<<ss;
			ss&=sb[j];
			//		cout<<ss;
			int num=ss.count();
			if (num<=1)
				continue;
			else
			{
				ans+=num*(num-1)/2;
			}
		}
	}
	
}


你可能感兴趣的:(ZOJ 2975-K - Kinds of Fuwas-暴力+bitset)