矩阵乘积
题目链接:传送门
题目大意:给你三个矩阵且三个矩阵从左至右满足矩阵乘法,现在给你很多组矩阵元素三元表示法,求三个矩阵从左至右相乘后第x行第y列的值。
题目思路:模拟即可
因为每个矩阵的大小<=6000,所以如果直接开3*6000*6000的数组是行不通的,我们注意到只需要乘法运算后第x行第y列的值,根据线性代数
的知识,就是第一个矩阵的第x行与第二个矩阵所有列相乘,在与第三个矩阵的第y列相乘即可。关键是处理乘法的时候怎么样模拟出来而又不废空间。
我们知道两矩阵相乘后得到的矩阵第x行第y列就是原来左边的矩阵第x行乘以右边矩阵第y列的所有元素。
题目中矩阵元素又是由三元表示法来表示,相当于简化了我们的计算,那么我们开3*6000的数组,第一个6000保存的是第一个矩阵第n行第m列的元素(n==x)
因为我们最后只需要求第x行,所以其他行的元素不需要保存,我们只需记录第几列即可。
第二个6000保存的是第一个矩阵和第二个矩阵相乘后得到的矩阵,同样只需要保留第几列,但这里需要注意,给你的三元组假如是 a b c
那么我们要用第一个矩阵的第x行第a列的元素乘以第二矩阵第a行第b列的元素,将所得结果保留到 a[1][b],因为得到的矩阵是 x*b,保留列
第三个6000保存的和第二同理,然后输出 a[2][y]既是答案。
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <algorithm> #include <cstring> #include <stack> #include <cctype> #include <queue> #include <string> #include <vector> #include <set> #include <map> #include <climits> #define lson root<<1,l,mid #define rson root<<1|1,mid+1,r #define fi first #define se second #define ping(x,y) ((x-y)*(x-y)) #define mst(x,y) memset(x,y,sizeof(x)) #define mcp(x,y) memcpy(x,y,sizeof(y)) using namespace std; #define gamma 0.5772156649015328606065120 #define MOD 1000000007 #define inf 0x3f3f3f3f #define N 2000005 #define maxn 100005 typedef pair<int,int> PII; typedef long long LL; int n,m,p,sx,sy; int a1,a2,a3,a4; int a[3][6005],b[3]; char str[600000]; int num(int x){ int len=0; while(x){ ++len; x/=10; } return len; } void get(int xx){ while(gets(str)){ if(!strcmp("\0",str))break; int len=strlen(str),i=0,cnt=-1; while(i<len){ if(isdigit(str[i])){ b[++cnt]=atoi(str+i); i+=num(b[cnt]); } ++i; } if(xx==0){ if(b[0]==sx) a[0][b[1]]=b[2]; } else if(xx==1){ a[1][b[1]]+=a[0][b[0]]*b[2]; } else{ if(b[1]==sy) a[2][sy]+=a[1][b[0]]*b[2]; } } } int main(){ int i,j,group,x,y,v,temp; scanf("%d%d",&sx,&sy);gets(str); scanf("%d%d%d%d",&a1,&a2,&a3,&a4);gets(str); get(0); get(1); get(2); printf("%d\n",a[2][sy]); return 0; }