bitset好神奇==
因为是A*B,而且A,B的元素mod之后只有0、1、2,所以用A[i][k]保存A的第i行数为k的元素的位置,用一个二进制数状态压缩表示,例如A[i][k]=1001,则表示A[i][0]=k,A[i][3]=k
将B转置存储,所以用B[j][k]保存B的第j行数为k的元素的位置。
aij,bij有一者为0时对cij不会有影响,A[i][1]&B[j][1]表示A的行i为1且B的列j为1,可以用count()统计个数,A[i][2]&B[j][2]表示A的行i为2且B的列j为2,因为2*2=4,所以最后要count()*4。只要枚举出1*1,1*2,2*1,2*2几种case即可。
#include<iostream>
#include<stdio.h>
#include<cstdio>
#include<stdlib.h>
#include<vector>
#include<string>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<stack>
#include<queue>
#include <ctype.h>
#include<map>
#include<time.h>
#include<bitset>
using namespace std;
//hdu 4920
const int maxn=810;
int n;
bitset<maxn>A[maxn][3];//<>内为长度,不是int
bitset<maxn>B[maxn][3];
int c[maxn][maxn];
int main()
{
freopen("input.txt","r",stdin);
//freopen("data.txt","r",stdin);
//freopen("out1.txt","w",stdout);
while(scanf("%d",&n)!=EOF)
{
long long k=0;
for(int i=0;i<n;i++)
{
for(int j=0;j<3;j++)//之前写成了n,居然T了==
{
A[i][j].reset();
B[i][j].reset();
}
}
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
scanf("%I64d",&k);
A[i][k%3].set(j);//A的第i行 k%3的数位于第几列,列数用二进制数表示
}
}
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
scanf("%I64d",&k);
B[j][k%3].set(i);//B的第j行 k%3的数位于第几行,行数用二进制数表示
//因为是矩阵相乘,所以要将B转置存储
}
}
for(int i=0;i<n;i++)//第i行
{
for(int j=0;j<n;j++)//第j列
{
c[i][j]=(A[i][1]&B[j][1]).count()+(A[i][1]&B[j][2]).count()*2+(A[i][2]&B[j][1]).count()*2+(A[i][2]&B[j][2]).count()*4;
c[i][j]%=3;
if(j==n-1) printf("%d\n",c[i][j]);
else printf("%d ",c[i][j]);
}
}
}
return 0;
}