Matrix multiplication
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 1928 Accepted Submission(s): 872
Problem Description
Given two matrices A and B of size n×n, find the product of them.
bobo hates big integers. So you are only asked to find the result modulo 3.
bobo hates big integers. So you are only asked to find the result modulo 3.
Input
The input consists of several tests. For each tests:
The first line contains n (1≤n≤800). Each of the following n lines contain n integers -- the description of the matrix A. The j-th integer in the i-th line equals A ij. The next n lines describe the matrix B in similar format (0≤A ij,B ij≤10 9).
The first line contains n (1≤n≤800). Each of the following n lines contain n integers -- the description of the matrix A. The j-th integer in the i-th line equals A ij. The next n lines describe the matrix B in similar format (0≤A ij,B ij≤10 9).
Output
For each tests:
Print n lines. Each of them contain n integers -- the matrix A×B in similar format.
Print n lines. Each of them contain n integers -- the matrix A×B in similar format.
Sample Input
1 0 1 2 0 1 2 3 4 5 6 7
Sample Output
0 0 1 2 1
Author
Xiaoxu Guo (ftiasch)
Source
2014 Multi-University Training Contest 5
第一次接触bitset,纠结了好久,也光是调试就调试了二十多分钟,听说还可以用n3解决,不过要改变循环的顺序;
下面这句是抄大神的;
以下是我的bitset代码:
AC 代码
第一次接触bitset,纠结了好久,也光是调试就调试了二十多分钟,听说还可以用n3解决,不过要改变循环的顺序;
下面这句是抄大神的;
这样写会超时: for (int i=1; i<=n; i++) for (int j=1; j<=n; j++) for (int k=1; k<=n; k++) c[i][j]+=a[i][k]*b[k][j]; 这样写就能过: for (int k=1; k<=n; k++) for (int i=1; i<=n; i++) for (int j=1; j<=n; j++) c[i][j]+=a[i][k]*b[k][j];
我们知道内存中二维数组是以行为单位连续存储的,逐列访问将会每次跳1000*4(bytes)。根据cpu cache的替换策略,将会有大量的cache失效。 时间居然会相差很多。
以下是我的bitset代码:
AC 代码
/****************************************************** /
/* /*
* *********** *
* * Auther: ZSGG *
* * *
* * Name: bitset *
* * *
* *********** Algorithm: *
* *
*/
/*******************************************************/
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <bitset>
#include <queue>
#include <vector>
#include <cstdlib>
#include <algorithm>
#define ls u << 1
#define rs u << 1 | 1
#define lson l, mid, u << 1
#define rson mid + 1, r, u << 1 | 1
using namespace std;
const int M = 810;
int b[M][M],n;
int main()
{
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
bitset<810>t[M][3]; //Every elements has eight hundrys and ten elements;
bitset<810>s[M][3];
while(~scanf("%d",&n))
{
for(int i = 1; i <= n; i++) //清空bitset容器;
{
for(int j = 1; j < 3; j++)
{
t[i][j].reset();
s[i][j].reset();
}
}
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
{
int x;
scanf("%d",&x);
x %= 3;
if(x) t[i][x][j] = 1; //在t[i][x]这个元素的第j个位置设置为1;
}
}
// 用bitset可以固定位置,这可以提高效率,使内层循环从n缩小为2 * 2; 详细看下面的代码;
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
{
scanf("%d",&b[i][j]);
b[i][j] %= 3;
}
}
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
{
if(b[j][i]) s[i][b[j][i]][j] = 1; //按列进bitset
}
}
/*核心代码*/
/*************************************************************/
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
{
int res = 0;
for(int p = 1; p <= 2; p++)
{
for(int k = 1; k <= 2; k++)
{
res += (t[i][p] & s[j][k]).count() * p * k; // 求出行和列的并集个数;如 0010 1010 交集个数为1;
}
}
printf(j == n ? "%d\n" : "%d ", res % 3);
}
}
/************************************************************/
}
return 0;
}
AC 代码:
/****************************************************** /
/* /*
* *********** *
* * Auther: ZSGG *
* * *
* * Name: bitset *
* * *
* *********** Algorithm: *
* *
*/
/*******************************************************/
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <bitset>
#include <queue>
#include <vector>
#include <cstdlib>
#include <algorithm>
#define ls u << 1
#define rs u << 1 | 1
#define lson l, mid, u << 1
#define rson mid + 1, r, u << 1 | 1
using namespace std;
const int M = 810;
int a[M][M],b[M][M],c[M][M];
int main()
{
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
int n;
while(~scanf("%d",&n))
{
memset(c,0,sizeof(c));
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
{ scanf("%d",&a[i][j]); a[i][j] %= 3; }
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
{ scanf("%d",&b[i][j]); b[i][j] %= 3; }
for(int k = 1; k <= n; k++)
{
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
{
c[i][j] += b[k][j] * a[i][k];
}
}
}
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
{
if(j == n) printf("%d\n",c[i][j] % 3);
else printf("%d ",c[i][j] % 3);
}
}
}
return 0;
}