CCF-CSP 202305-2矩阵运算

题目

解题过程

花了一个多小时写了第一版代码。

#include<iostream>
using namespace std;
typedef long long ll;
const int MAXN=1e4+2;
const int MAXD=21;
int n,d;
ll q[MAXN][MAXD],k[MAXN][MAXD],v[MAXN][MAXD],w[MAXN];

int main(){
	cin>>n>>d;//矩阵大小 
	for(int i=1;i<=n;i++){//n行 
		for(int j=1;j<=d;j++){//d列 
			cin>>q[i][j];
		}
	}
	for(int i=1;i<=n;i++){//n行 
		for(int j=1;j<=d;j++){//d列 
			cin>>k[i][j];
		}
	}
	for(int i=1;i<=n;i++){//n行 
		for(int j=1;j<=d;j++){//d列 
			cin>>v[i][j];
		}
	}
	for(int i=1;i<=n;i++){
		cin>>w[i];
	}
	ll ans[MAXN][MAXD];
	ll qktij;
	for(int i=1;i<=n;i++){//i行 
		for(int j=1;j<=n;j++){//j列
			qktij=0;
			//得到最终数组的顺序是先从左到右再从上到下 
			//i行乘j列对应元素最后相加,f循环结束就是这一个元素的最终值 
			for(int f=1;f<=d;f++){
				qktij+=q[i][f]*k[j][f];
			}
			qktij*=w[i];
			for(int x=1;x<=d;x++){
				ans[i][x]+=qktij*v[j][x];
			}
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=d;j++){
			cout<<ans[i][j]<<" ";
		}
		cout<<endl;
	}
	return 0;
}

提交后发现没过


很疑惑,不知道为什么答案错误,总的运算是跟矩阵乘法一样的,能过前70%,但是最后30%报错,大小存储也合适,时间也没超。
按理说能过70%后面也能过,除非是内存问题或者超时了。

·
·
·

对比了别人的代码,修改了我自己代码中可能有问题的部分代码后重新提交

#include<iostream>
using namespace std;
typedef long long ll;
const int MAXN=1e4+5;
const int MAXD=25;
int n,d;
ll q[MAXN][MAXD],k[MAXN][MAXD],v[MAXN][MAXD],w[MAXN];

int main(){
	cin>>n>>d;//矩阵大小 
	for(int i=1;i<=n;i++){//n行 
		for(int j=1;j<=d;j++){//d列 
			cin>>q[i][j];
		}
	}
	for(int i=1;i<=n;i++){//n行 
		for(int j=1;j<=d;j++){//d列 
			cin>>k[i][j];
		}
	}
	for(int i=1;i<=n;i++){//n行 
		for(int j=1;j<=d;j++){//d列 
			cin>>v[i][j];
		}
	}
	for(int i=1;i<=n;i++){
		cin>>w[i];
	}
	ll ans[MAXN][MAXD];
	ll qktij;
	ll qkti[MAXN];
	for(int i=1;i<=n;i++){//i行 
		for(int j=1;j<=n;j++){//j列
			qktij=0;
			qkti[j]=0;
			//得到最终数组的顺序是先从左到右再从上到下 
			//i行乘j列对应元素最后相加,f循环结束就是这一个元素的最终值 
			for(int f=1;f<=d;f++){
				//qktij+=q[i][f]*k[j][f];
				qkti[j]+=q[i][f]*k[j][f];
			}
			qkti[j]*=w[i];
		}
		for(int j=1;j<=d;j++){
			ll tmp=0;
			for(int f=1;f<=n;f++){
				tmp+=qkti[f]*v[f][j];
			}
			cout<<tmp<<" ";
		}
		cout<<endl;
	}
	return 0;
}

答案正确了但是超时

重新整理逻辑修改代码ing(换成别人的代码仍然不通过,一个头两个大)

·
·
·

进行了简单的尝试,解决了,一个很好的教训,数组初始化要放在main函数外面,不然不会初始化,或者在定义数组的时候初始化
以前都会立刻初始化,今天第一次去掉这玩意就出问题了,也算多知道了一点知识,多踩一次坑。

就因为这个改了一个小时的代码,你干的好啊(赞赏)。


以下AC代码对比第一次的代码区别只将数组初始化放在了main函数外面(后面经过尝试,发现就是数组未初始化导致的内存问题,只要初始化数组就能通过了,不管是放在main函数外面还是在main函数中定义同时初始化都可以)。

#include<iostream>
using namespace std;
typedef long long ll;
const int MAXN=1e4+5;
const int MAXD=25;
int n,d;
ll q[MAXN][MAXD],k[MAXN][MAXD],v[MAXN][MAXD],w[MAXN];
ll ans[MAXN][MAXD];
ll qktij;

int main(){
	cin>>n>>d;//矩阵大小 
	for(int i=1;i<=n;i++){//n行 
		for(int j=1;j<=d;j++){//d列 
			cin>>q[i][j];
		}
	}
	for(int i=1;i<=n;i++){//n行 
		for(int j=1;j<=d;j++){//d列 
			cin>>k[i][j];
		}
	}
	for(int i=1;i<=n;i++){//n行 
		for(int j=1;j<=d;j++){//d列 
			cin>>v[i][j];
		}
	}
	for(int i=1;i<=n;i++){
		cin>>w[i];
	}
	//ll ans[MAXN][MAXD]={{0}};//定义数组时初始化也可以,千万不要为了让代码看起来简洁就不写这个初始化,这次省略的很好,下次别省了
	for(int i=1;i<=n;i++){//i行 
		for(int j=1;j<=n;j++){//j列
			qktij=0;
			//得到最终数组的顺序是先从左到右再从上到下 
			//i行乘j列对应元素最后相加,f循环结束就是这一个元素的最终值 
			for(int f=1;f<=d;f++){
				qktij+=q[i][f]*k[j][f];
			}
			qktij*=w[i];
			for(int x=1;x<=d;x++){
				ans[i][x]+=qktij*v[j][x];
			}
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=d;j++){
			cout<<ans[i][j]<<" ";
		}
		cout<<endl;
	}
	return 0;
}

记录一下

posted @ 2024-03-14 20:01  skdtxdy  阅读(159)  评论(0编辑  收藏  举报