当前位置: 首页 > article >正文

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

矩阵运算

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

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

暴力超时法:70分

#include <iostream>
#include <vector>
using namespace std;
#define ll long long


int 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;
}


http://www.kler.cn/a/301294.html

相关文章:

  • 一文了解 inductive bias(归纳偏好)
  • android 如何获取当前 Activity 的类名和包名
  • 机器学习(西瓜书)-BP神经网络实现
  • Django5 2024全栈开发指南(二):Django项目配置详解
  • PHP 表单 - 必需字段
  • 【微信小程序】访客管理
  • 深度学习驱动的车牌识别:技术演进与未来挑战
  • 主窗口的设计与开发(二)
  • 3、三维重建-NeuralRecon
  • 东莞网站制作-如何优化推广
  • web框架
  • 【linux】一种基于虚拟串口的方式使两个应用通讯
  • 使用kubeadm手动安装K8s
  • C++学习笔记----6、内存管理(五)---- 智能指针(4)
  • 使用patch命令移除sts中的一个container
  • 【CTF Web】BUUCTF Upload-Labs-Linux Pass-13 Writeup(文件上传+PHP+文件包含漏洞+JPEG图片马)
  • 力扣100题——动态规划
  • 【MATLAB】数据和字符串类型转换
  • 路由器出现DNS(Domain Name System)没有被解析的情况,没有被解析的情况,通常是由多种原因导致的。以下是一些可能的原因及相应的解释:
  • TDSQL:腾讯分布式数据库系统的核心要点与优势分析
  • Java之枚举
  • macos 系统文件操作时提示 Operation not permitted 异常解决方法 , 通过恢复模式 开启 /关闭 SIP方法
  • debian12实践-安装docker
  • 日志框架log4j打印异常堆栈信息携带traceId,方便接口异常排查
  • Redisson实现订单到期关闭
  • 论文阅读_检索增强生成 RAG 综述