CSP 202305-2 矩阵运算

样例输入

3 2
1 2
3 4
5 6
10 10
-20 -20
30 30
6 5
4 3
2 1
4 0 -5

样例输出

480 240
0 0
-2200 -1100

答题

注意数值范围用int已经不行了,必须要用long long

而且矩阵运算涉及到三层循环,可以利用cache机制减少取值时间,先将右矩阵转置再计算

最关键的是由于d远远小于n,所以先计算KTV得到的dxd大小的矩阵要远远小于先计算QKT得到的nxn大小的矩阵,无论是存储上还是计算上都会大大减少时间

#include <iostream>
using namespace std;
long long** makeMatrix(int n,int d){
    auto**p=new long long * [n];
    for(long long i=0;i<n;i++){
        p[i]=new long long[d];
    }
    return p;
}
void inputTurn(long long**p, int n, int d){
    for(int i=0;i<n;i++)
        for(int j=0;j<d;j++){
            cin>>p[j][i];
        }
}
int main(){
    int n,d;
    cin>>n>>d;
    long long **Q= makeMatrix(n,d);
    long long **K= makeMatrix(d,n);
    long long **V= makeMatrix(d,n); // 利用cache将V转置存储
    auto *W=new long long [n];
    long long **result= makeMatrix(n,d);
    for(int i=0;i<n;i++)
        for(int j=0;j<d;j++){
            cin>>Q[i][j];
        }
    inputTurn(K, n, d);
    inputTurn(V, n, d);
    for(int i=0;i<n;i++){
        cin>>W[i];
    }
    long long **KTV= makeMatrix(d, d);
    for(int i=0;i<d;i++)
        for(int j=0;j<d;j++){
            KTV[i][j]=0;
            for(int k=0;k<n;k++){
                KTV[i][j]+= K[i][k] * V[j][k];
            }
        }
    for(int i=0;i<n;i++)
        for(int j=0;j<d;j++){
            result[i][j]=0;
            for(int k=0;k<d;k++){
                result[i][j]+= Q[i][k] * KTV[k][j];
            }
        }
    for(int i=0;i<n;i++)
        for(int j=0;j<d;j++){
            result[i][j]*=W[i];
        }
    for(int i=0;i<n;i++){
        for(int j=0;j<d-1;j++){
            cout<<result[i][j]<<' ';
        }
        cout<<result[i][d-1]<<endl;
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_62264287/article/details/132675310
CSP