蓝桥杯之算法很美课程第四章习题 稀疏矩阵乘积
题目描述:
给定两个N × N的稀疏矩阵A和B,其中矩阵A有P个元素非0,矩阵B有Q个元素非0。请计算两个矩阵的乘积C = A × B并且输出C中所有非0的元素。
输入
第一行包含三个整数N, P, Q
以下P行每行三个整数i, j, k表示A矩阵的一个非0元素:Aij = k
以下Q行每行三个整数i, j, k表示B矩阵的一个非0元素:Bij = k
对于80%的数据,1 ≤ N, P, Q ≤ 200
对于100%的数据, 1 ≤ N, P, Q ≤ 2000, 1 ≤ i, j ≤ N, 0 ≤ k ≤ 100
输出
输出若干行,按先行后列的顺序输出矩阵C的每一个非0元素
每行三个整数i, j, k表示C矩阵的一个非0元素:Cij = k
样例输入
2 2 4
1 1 1
2 2 1
1 1 1
1 2 2
2 1 3
2 2 4
样例输出
1 1 1
1 2 2
2 1 3
2 2 4
如果直接暴力破解求解,时间复杂度为O(n^3),核心代码如下:
for(i = 0; i < n; ++i)
{
for(j = 0; j < n; ++j)
{
for(k = 0; k < n; ++k)
{
c[i][j] += a[i][k] * b[k][j];
}
}
}
按照题意,最多只能通过80%的数据,我试着提交了下,只得了70分,说明这种方法能通过70%的数据。
要尝试将时间复杂度降为O(n^2),思路大致如下:
设定一个三元数组结构体,结构体的元素有x,y,d分布代表横纵坐标和数值大小,当顺序取到a[i][k]时,为了高效地到矩阵b的三元组中抽取所有行号为k的元素,只要知道那些元素的起始位置及个数即可,因为行号为k的三元组都集中在一起.建立两个辅助数组:rowsize[],用来存放矩阵B各行的非零元素个数,rowstart[],用来存放b各行非零元素在三元组表中的起始位置。具体代码如下:
#include<iostream>
using namespace std;
struct s
{
int x; int y; int d;
}a[2002], b[2002], c[2002];
int rowsize[2000] = {
0}, rowstart[2001] = {
0};
int temp[2000] = {