欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 产业 > CCF刷题计划——矩阵运算(同时转置+乘法)

CCF刷题计划——矩阵运算(同时转置+乘法)

2024/10/25 2:22:06 来源:https://blog.csdn.net/Caspiannn/article/details/142125265  浏览:    关键词:CCF刷题计划——矩阵运算(同时转置+乘法)

矩阵运算

计算机软件能力认证考试系统

现在这分也越来越难挣咯~这也超时,那也超时的。但是也给我们一个矩阵优化的思路,那就是 同时转置+乘法。下面给出超时和AC。

暴力超时法:70分

#include <iostream>
#include <vector>
using namespace std;
#define ll long longint n,d;//矩阵大小 vector<vector<ll>> Trans(vector<vector<ll>>K)	//转置
{vector<vector<ll>>temp(d,vector<ll>(n,0));for(int i=0;i<d;i++)for(int j=0;j<n;j++)temp[i][j]=K[j][i];return temp;} ll Mul_tensor(int row,int col,vector<vector<ll>>Q,vector<vector<ll>>K)
{ll c=0;for(int i=0;i<Q[0].size();i++)	c+=Q[row][i]*K[i][col];return c;
}vector<vector<ll>> Mul_matrix(vector<vector<ll>>Q,vector<vector<ll>>K)
{vector<vector<ll>>temp(Q.size(),vector<ll>(K[0].size(),0));for(int i=0;i<Q.size();i++)	//取Q的行数 {for(int j=0;j<K[0].size();j++)	//K的列数 {temp[i][j]=Mul_tensor(i,j,Q,K);}}return temp;
}int main() 
{cin>>n>>d; vector<vector<ll>>Q(n);vector<vector<ll>>K(n);vector<vector<ll>>V(n);int t;for(int i=0;i<n;i++)for(int j=0;j<d;j++){cin>>t;Q[i].push_back(t);} for(int i=0;i<n;i++)for(int j=0;j<d;j++){cin>>t;K[i].push_back(t);} vector<vector<ll>>Kt=Trans(K);vector<vector<ll>>QKt=Mul_matrix(Q,Kt);for(int i=0;i<n;i++)for(int j=0;j<d;j++){cin>>t;V[i].push_back(t);}int w;for(int i=0;i<n;i++){cin>>w;for(int j=0;j<QKt[0].size();j++)QKt[i][j]*=w;}vector<vector<ll>>ans=Mul_matrix(QKt,V);for(int i=0;i<ans.size();i++){for(int j=0;j<ans[0].size();j++)cout<<ans[i][j]<<" ";cout<<endl;}return 0;
}

优化:将乘法和转置一起处理

我们发现,当矩阵过大的时候,转置啊乘法啊什么的就会很费事。所以这里我们将转置合并到乘法里面去,同时在乘第二个矩阵的时候也把W乘进去。具体规律我写到了代码中,大家也可以自己手动画画。

AC:

#include <iostream>
#include <vector>
using namespace std;
#define ll long long//答案,优化策略是K一边置换一边乘V const int N=1e4+2; 
const int D=22; int n,d;//矩阵大小 
int K[N][D],Q[N][D],V[N][D]; 
int W[N];int main()
{cin>>n>>d; ll temp[D][D]={0};for(int i=0;i<n;i++)for(int j=0;j<d;j++)cin>>Q[i][j];for(int i=0;i<n;i++)for(int j=0;j<d;j++)cin>>K[i][j];for(int i=0;i<n;i++)for(int j=0;j<d;j++)cin>>V[i][j];for(int i=0;i<n;i++)	cin>>W[i];//转置和乘V一步到位//例如,C00=A00*B00+A01*B10+A02*B20,假如A是转置后的值,那转置前就是:A00,A10,A20//转化成就是C00= A00*B00+A10*B10+A20*B20// 同理,C01=A00*B01+A01*B11+A02*B21--> C01=A00*B01+A10*B11+A20*B21//总结出规律,我们发现AB都是相同行的值在乘 : for(int i=0;i<d;i++)for(int j=0;j<d;j++)for(int k=0;k<n;k++)temp[i][j] += K[k][i] * V[k][j];	//相同行匹配 ll ans[N][D]={0};//乘Q乘w一步到位 for(int i=0;i<n;i++){for(int j=0;j<d;j++){for(int k=0;k<d;k++)ans[i][j]+=Q[i][k]*temp[k][j];ans[i][j]*=W[i];}}for(int i=0;i<n;i++){for(int j=0;j<d;j++)cout<<ans[i][j]<<" ";cout<<endl;}return 0;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com