https://www.nowcoder.com/acm/contest/202/A
题意:
给你两个矩阵,做乘法之后,算出所有元素异或后的答案。
POINT:
把N x P, P x M的两个矩阵,都对p分为每8个一份。
对n行的p个数,每8个数一组,把所有选取的状态全部处理出来,8个数选或不选,就是2^8=256种情况。
算出每种状态的和。效率为o(n*p*256)。
然后把第二个矩阵也8个8个处理,不过这8个01就是我们对应的状态了。
然后对于每一行(1-n),这p/8个数,对应的状态直接套上,相当于O1查询了。
#include <stdio.h>
#include <vector>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <queue>
using namespace std;
#define LL long long
const int N = 1111+55;
int sum[4100][10][300];
int kind[4100][10];
int b[4100][70];
int a[4100][70];
int main()
{
int n,p,m;
scanf("%d%d%d",&n,&p,&m);
for(int i=0;i<n;i++){
for(int j=0;j<p;j++){
scanf("%x",&a[i][j]);
}
}
for(int i=0;i<m;i++){
char s[70];
scanf("%s",s);
for(int j=0;j<p;j++){
b[i][j]=s[j]-'0';
}
}
p=(p-1)/8+1;
for(int i=0;i<n;i++){
for(int j=0;j<p;j++){
int pos=j*8;
for(int k=0;k<256;k++){
int s=0;
for(int x=0;x<8;x++){
if(k&(1<<x)) s+=a[i][pos+x];
}
sum[i][j][k]=s;
}
}
}
for(int i=0;i<m;i++){
for(int j=0;j<p;j++){
int pos=j*8;
int now=0;
for(int k=0;k<8;k++){
if(b[i][pos+k])
now|=1<<k;
}
kind[i][j]=now;
}
}
int ans=0;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
int s=0;
for(int k=0;k<p;k++){
s+=sum[i][k][kind[j][k]];
}
ans=ans^s;
}
}
printf("%d\n",ans);
}