您的位置:首页 > 其它

HDU 4920 Matrix multiplication(矩阵相乘小优化)

2015-09-19 21:00 309 查看
题目链接:HDU 4920

【题目大意】

简单的两个 n x n的矩阵相乘, 但是对时间要求比较苛刻。

因为c++默认数据优先按行存储,对c理解较深的同学也知道,数组在内存中是用一段连续的空间保存二维数组的,所以按行取元素比按列取元素要快

【代码分析】

一般正常人的思维,二维数组的相乘是这样写的,不就是模拟矩阵相乘嘛~

for(int i=0;i<n;i++)
    for(int j=0;j<n;j++){
        int sum = 0;
        for(int k=0;k<n;k++){
            sum += (matrixA[i][k]*matrixB[k][j]);
        }    
        ans[i][j] = sum;
    }


可是对于对时间要求比较严格的这个题目来说,就太慢了,超时!

因此,如上所述,利用c++默认数据优先按行存储,按行取元素比按列取元素要快这一特点,我们可以这样来写矩阵的相乘

memset(ans,0,sizeof(ans));	//记住要先清零
for(int i=0;i<n;i++)
	for(int k=0;k<n;k++)
		for(int j=0;j<n;j++){
			ans[i][j] += (matrixA[i][k]*matrixB[k][j]);
		}


仔细对照上下两个代码,可以自己举个例子模拟下算法的运行。

可以看出,下面的代码充分利用了 系统的储存特点 , 使得每次ans【】【】数组的求和 , 几乎都是沿着“内存条”进行定位赋值的。

这样这个题基本上就 OK 了。

【源代码】

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 810;
int matrixA[maxn][maxn];
int matrixB[maxn][maxn];
int ans[maxn][maxn];
int main(){
	int n;
	while(scanf("%d",&n)!=EOF ){
		for(int i=0;i<n;i++)
			for(int j=0;j<n;j++){
				scanf("%d",&matrixA[i][j]);
				matrixA[i][j]%=3; //先进行取余操作
			}
		for(int i=0;i<n;i++)
			for(int j=0;j<n;j++){
				scanf("%d",&matrixB[i][j]);
				matrixB[i][j]%=3;
			}
		memset(ans,0,sizeof(ans));		
		for(int i=0;i<n;i++)
			for(int k=0;k<n;k++)
				for(int j=0;j<n;j++){
					ans[i][j] += (matrixA[i][k]*matrixB[k][j]);
				}
		for(int i=0;i<n;i++){
			for(int j=0;j<n;j++){
				if(j!=0)
					printf(" %d",ans[i][j]%3); // 输出时再取余
				else 
					printf("%d",ans[i][j]%3);
			}
			printf("\n");
		}
	}
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: