给出一个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; } } } }