hdu 4920 Matrix multiplication(矩陣相乘)多校訓練第5場,hdumultiplication
Matrix multiplication Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Problem DescriptionGiven 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.
InputThe 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).
OutputFor each tests:
Print n lines. Each of them contain n integers -- the matrix A×B in similar format.
Sample Input
10120 12 34 56 7
Sample Output
00 12 1
題意:給出兩個n*n的矩陣,求這兩個矩陣的乘積,結果對3取餘。分析:拿到題先用了經典的矩陣相乘的方法,提交以後果斷逾時了。後來在網上搜了一下矩陣相乘最佳化,找到了一個最佳化方法,只可惜現在我還沒有理解是怎麼最佳化的。
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int N = 805;int a[N][N], b[N][N], ans[N][N];void Multi(int n){ int i, j, k, L, *p2; int tmp[N], con; for(i = 0; i < n; ++i) { memset(tmp, 0, sizeof(tmp)); for(k = 0, L = (n & ~15); k < L; ++k) { con = a[i][k]; for(j = 0, p2 = b[k]; j < n; ++j, ++p2) tmp[j] += con * (*p2); if((k & 15) == 15) { for(j = 0; j < n; ++j) tmp[j] %= 3; } } for( ; k < n; ++k) { con = a[i][k]; for(j = 0, p2 = b[k]; j < n; ++j, ++p2) tmp[j] += con * (*p2); } for(j = 0; j < n; ++j) ans[i][j] = tmp[j] % 3; }}int main(){ int n, i, j, k; while(~scanf("%d",&n)) { for(i = 0; i < n; i++) for(j = 0; j < n; j++) { scanf("%d",&a[i][j]); a[i][j] %= 3; } for(i = 0; i < n; i++) for(j = 0; j < n; j++) { scanf("%d",&b[i][j]); b[i][j] %= 3; } Multi(n); for(i = 0; i < n; i++) { for(j = 0; j < n-1; j++) printf("%d ", ans[i][j]); printf("%d\n", ans[i][n-1]); } } return 0;}
http://blog.csdn.net/gogdizzy/article/details/9003369這裡面講解了矩陣相乘的最佳化方法。
下面這種方法也可以過:
#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>using namespace std;const int N = 805;int a[N][N], b[N][N], ans[N][N];int main(){ int n, i, j, k; while(~scanf("%d",&n)) { for(i = 1; i <= n; i++) for(j = 1; j <= n; j++) { scanf("%d",&a[i][j]); a[i][j] %= 3; } for(i = 1; i <= n; i++) for(j = 1; j <= n; j++) { scanf("%d",&b[i][j]); b[i][j] %= 3; } memset(ans, 0, sizeof(ans)); for(k = 1; k <= n; k++) //經典演算法中這層迴圈在最內層,放最內層會逾時,但是放在最外層或者中間都不會逾時,不知道為什麼 for(i = 1; i <= n; i++) for(j = 1; j <= n; j++) { ans[i][j] += a[i][k] * b[k][j]; //ans[i][j] %= 3; //如果在這裡對3取餘,就逾時了 } for(i = 1; i <= n; i++) { for(j = 1; j < n; j++) printf("%d ", ans[i][j] % 3); printf("%d\n", ans[i][n] % 3); } } return 0;}