P2222 [HNOI2001] 矩阵乘积
题目描述
已知矩阵:
Am×n=[a1,1a1,2⋯a1,na2,1a2,2⋯a2,n⋮⋮⋱⋮am,1am,2⋯am,n],Bn×p=[b1,1b1,2⋯b1,pb2,1b2,2⋯b2,p⋮⋮⋱⋮bn,1bn,2⋯bn,q]A_{m\times n}=\begin{bmatrix}a_{1,1} & a_{1,2} & \cdots & a_{1,n}\\ a_{2,1} & a_{2,2} & \cdots & a_{2,n} \\ \vdots & \vdots & \ddots & \vdots\\ a_{m,1} & a_{m,2} & \cdots &a_{m,n} \end{bmatrix} ,B_{n\times p}=\begin{bmatrix}b_{1,1} & b_{1,2} & \cdots & b_{1,p}\\ b_{2,1} & b_{2,2} & \cdots & b_{2,p} \\ \vdots & \vdots & \ddots & \vdots\\ b_{n,1} & b_{n,2} & \cdots &b_{n,q} \end{bmatrix}Am×n=a1,1a2,1⋮am,1a1,2a2,2⋮am,2⋯⋯⋱⋯a1,na2,n⋮am,n,Bn×p=b1,1b2,1⋮bn,1b1,2b2,2⋮bn,2⋯⋯⋱⋯b1,pb2,p⋮bn,q
当矩阵 AAA 的列数与矩阵 BBB 的行数相同时,则 AAA 与 BBB 可以相乘,其乘积为一个 m×pm\times pm×p 的矩阵 DDD:
Dm×p=[d1,1d1,2⋯d1,pd2,1d2,2⋯d2,p⋮⋮⋱⋮dm,1dm,2⋯dm,p]D_{m\times p}=\begin{bmatrix} d_{1,1} & d_{1,2} & \cdots & d_{1,p}\\ d_{2,1} & d_{2,2} & \cdots & d_{2,p} \\ \vdots & \vdots & \ddots & \vdots\\ d_{m,1} & d_{m,2} & \cdots & d_{m,p}\end{bmatrix}Dm×p=d1,1d2,1⋮dm,1d1,2d2,2⋮dm,2⋯⋯⋱⋯d1,pd2,p⋮dm,p
其中 di,j=∑k=1nai,k×bk,jd_{i,j}=\sum^n_{k=1} a_{i,k} \times b_{k,j}di,j=∑k=1nai,k×bk,j,简记为 D=A×BD=A\times BD=A×B。
现已知三个矩阵 A,B,CA,B,CA,B,C,这三个矩阵大多数元素为 000,我们把这种矩阵称为稀疏矩阵。因此,我们采用三元组 i,j,ai,j,ai,j,a 来表示矩阵的第 iii 行第 jjj 列的值为 aaa 其余未列出的元素均为 000;在计算机中,我们仅给出非零元素的三元组,而且使用行优先法给出稀疏矩阵的三元组,首先是第一行按列给出,然后是第二行按列给出……
例如,矩阵:[1000002−101230000]\begin{bmatrix}1&0&0&0\\0&0&2&-1\\0&1&2&3\\0&0&0&0\end{bmatrix}1000001002200−130 那么,矩阵的三元组表示为:
1 1 1
2 3 2
2 4 -1
3 2 1
3 3 2
3 4 3
你的任务就是:计算矩阵 D=A×B×CD=A\times B\times CD=A×B×C。
输入格式
第一行为两个正整数 x,yx,yx,y,分别表示输出结果所在的行和列。
第二行为四个整数 m,n,o,pm,n,o,pm,n,o,p,表明 AAA 为m×nm\times nm×n 的矩阵,BBB 为 n×on\times on×o 的矩阵,CCC 为 o×po\times po×p 的矩阵。
第三行以后的每一行有三个整数分别是矩阵的三元组表示法中的一个元素的值,每个矩阵之间有一个空行。表示的顺序是矩阵 A,B,CA,B,CA,B,C。
输出格式
仅一个整数,为 DDD 的第 xxx 行第 yyy 列的元素的值。
输入输出样例 #1
输入 #1
1 2
3 4 2 3
1 1 3
1 4 5
2 2 1
3 1 2
1 2 2
2 1 1
3 1 2
3 2 4
1 2 2
1 3 3
2 1 1
2 2 2
输出 #1
12
说明/提示
数据规模与约定
对于全部的测试点,保证 1≤m,n,o,p≤6×1031\le m,n,o,p\le 6\times 10^31≤m,n,o,p≤6×103,三元数组的总个数不大于 6×1036\times 10^36×103。数据之间用空格分开。
C++实现
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <cctype>
using namespace std;
typedef long long ll;
int x,y,m,n,o,p;
int Am[6005]={0},Bm[6005]={0};
char input[10005];
int main(){
int i,j,u,v,val;
scanf("%d%d%d%d%d%d",&x,&y,&m,&n,&o,&p);
fgets(input,10000,stdin);
for(;;){
fgets(input,10000,stdin);
if(!isdigit(input[0]))break;
sscanf(input,"%d%d%d",&u,&v,&val);
if(u==x)Am[v]=val;
}
for(;;){
fgets(input,10000,stdin);
if(!isdigit(input[0]))break;
sscanf(input,"%d%d%d",&u,&v,&val);
Bm[v]+=Am[u]*val;
}
memcpy(Am,Bm,sizeof(Bm));
memset(Bm,0,sizeof(Bm));
while(~scanf("%d%d%d",&u,&v,&val))
Bm[v]+=Am[u]*val;
printf("%d\n",Bm[y]);
return 0;
}

后续
接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容
474

被折叠的 条评论
为什么被折叠?



