HDU 4920 矩阵乘积 优化
Matrix multiplication
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 1289 Accepted Submission(s): 568
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 Aij. The next n lines describe the matrix B in similar format (0≤Aij,Bij≤109).
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 Aij. The next n lines describe the matrix B in similar format (0≤Aij,Bij≤109).
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
#include <iostream> #include <string.h> #include <stdio.h> using namespace std; #define MAX 810 int a[MAX][MAX],b[MAX][MAX],c[MAX][MAX]; int main() { int n; while(~scanf("%d",&n)) { for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { scanf("%d",&a[i][j]); a[i][j]=a[i][j]%3; } } for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { scanf("%d",&b[i][j]); b[i][j]=b[i][j]%3; } } memset(c,0,sizeof(c)); for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { if(a[i][j]==0) continue; for(int k=0;k<n;k++) { c[i][k]+=a[i][j]*b[j][k]; 如果这里 c[i][k]+=(a[i][j]*b[j][k])%3;就会超时 } } } for(int i = 0; i < n; i++) { for(int j = 0; j < n; j++) if(j == 0) printf("%d", c[i][j]%3); else printf(" %d", c[i][j]%3); printf("\n"); } } return 0; }
#include <iostream> #include<stdio.h> #include<vector> ///他把所有的0都忽略了,很巧妙的优化,aa[][], bb[][]里存储的是下一个不为0的位置: #include<queue> #include<stack> #include<string.h> #include<algorithm> #include<map> using namespace std; #define LL long long #define gcd(a,b) (b==0?a:gcd(b,a%b)) #define lcm(a,b) (a*b/gcd(a,b)) //O(n)求素数,1-n的欧拉数 #define N 100010 //A^x = A^(x % Phi(C) + Phi(C)) (mod C) int a[880][880]; int aa[880][880]; int b[880][880]; int bb[880][880]; int c[880][880]; int main() { int n; while(~scanf("%d",&n)) { memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); memset(aa,0,sizeof(aa)); memset(bb,0,sizeof(bb)); 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; /// cout<<"%%%"<<a[i][j]<<endl; } } 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++) { int x=-1; for(int j=n; j>=0; j--) { aa[i][j]=x; ///后退了一位 所以j:n~~0 if(a[i][j]) x=j; //cout<<"~~~~"<<a[i][j]<<' '<<aa[i][j]<<endl;///记录矩阵中0的位置 赋值给aa【】【】 } } for(int i=1; i<=n; i++) { int x=-1; for(int j=n; j>=0; j--) { bb[i][j]=x; if(b[i][j])x=j; } } for(int i=1; i<=n; i++) { for(int j=aa[i][0]; j!=-1; j=aa[i][j]) { for(int k=bb[j][0]; k!=-1; k=bb[j][k]) ///a==0时 对应b那一列乘a==0 所以根据bb【j】来转变 c[i][k]+=a[i][j]*b[j][k]; } } for(int i=1; i<=n; i++) { for(int j=1; j<=n; j++) { printf("%d",c[i][j]%3); if(j!=n)printf(" "); else printf("\n"); } } } return 0; }