CCF-CSP真题202305-2矩阵运算(Java满分题解)

1.题目详情

2.矩阵运算的一些性质(在本题中用到的)

(1)乘法结合律,A(BC)=(AB)C
(2)两个矩阵相乘时要满足第一个矩阵的列数等于第二个矩阵的行数。例如:A(m×n) × B(n×p)=C(m×p)
(3)矩阵的转置就是将原来的行变为列,原来的列变为行。

3.思路

1)在CSP题中要特别注意题目中的提示语句:请谨慎评估矩阵乘法运算后的数值范围,并使用适当数据类型存储矩阵中的整数。往往提示语句决定了你是否能够得到满分。通过提示的这句话可以得出:矩阵乘法运算后的数值范围应该用long这种数据类型,并且在声明矩阵的大小时也应该遵循最大空间利用率的法则。
(2)观察运算的式子不难发现,向量W对矩阵的点乘本质上相当于是一种数乘,这个操作并不会对原有定义矩阵时声明的long类型造成内存溢出等情况。所以可以直接观察后面的两次乘法操作。
(3)若Q先和K矩阵的转置相乘,那么我们需要定义一个大小为n×n的二维数组,然后再乘矩阵V。还需定义一个大小为n×d的二维数组用来存放结果值。但是如果K矩阵的转置先和矩阵V相乘,则只需要定义一个d×d大小的数组。最后Q和这个数组相乘,定义一个n×d大小的二维数组用来存放结果值。
(4)由于题目中的n数量级要远远高于d,所以可以明显看出第二种的顺序要比第一种更加节省空间。所以我们选择第二种方式即可。

Java(100分)

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int d = sc.nextInt();
        int[][] Q = new int[n][d];
        int[][] K = new int[n][d];
        int[][] V = new int[n][d];
        int[] W = new int[n];
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < n; j++) {
                for (int k = 0; k < d; k++) {
                    if(i == 0){
                        Q[j][k] = sc.nextInt();
                    }else if(i == 1){
                        K[j][k] = sc.nextInt();
                    }else {
                        V[j][k] = sc.nextInt();
                    }
                }
            }
        }
        for (int i = 0; i < n; i++) {
            W[i] = sc.nextInt();
        }

        long[][] re1 = new long[d][d];
        for (int i = 0; i < d; i++) {
            for (int j = 0; j < d; j++) {
                for (int k = 0; k < n; k++) {
                    re1[i][j] += (long) V[k][j] * K[k][i];
                }
            }
        }

        long[][] re2 = new long[n][d];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < d; j++) {
                for (int k = 0; k < d; k++) {
                    re2[i][j] += (long)Q[i][k]*re1[k][j];
                }
                //这里的向量W其中的第i个值就要和矩阵中的第i行所有元素进行数乘运算。
                re2[i][j]*=W[i];
                System.out.print(re2[i][j] + " ");
            }
            System.out.println();
        }
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

北洋的霞洛

觉得不确可以给个鼓励小费

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值