[51nod - 1140] 矩阵相乘结果判定

本文介绍两种验证两个N×N矩阵相乘是否等于第三个N×N矩阵的方法。方法一通过直接计算矩阵乘法并比较结果,复杂度为Θ(N^3)。方法二采用随机向量验证,将复杂度降至O(CN^2),其中C为测试次数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:

给出三个 N×NN×N的矩阵 A,B,CA,B,C,问A×BA×B是否等于CC

分析:

方法1
X=A×B,可以O(N)O(N) 暴力算 Xi,jXi,j, 如果发现 Xi,jCi,jXi,j≠Ci,j 则可直接判定不等。最坏复杂度 Θ(N3)Θ(N3).

方法2
A×B=CA×B=C, 则对于任意一个 NN 维向量 V, 都有 V×A×B=V×CV×A×B=V×C。那么我们可以随机生成一个向量 VV, O(N2)测试是否有 V×A×B=V×CV×A×B=V×C 即可,复杂度降为 O(N2)O(N2),但是有一定可能存在错判,可以通过多试几次来减少错判的可能性,总复杂度 O(CN2)O(CN2),其中 CC 为测试次数。

在精度要求不是很严格的条件下,方法2显然是更优的,对于可以重复提交的算法竞赛中,可以使用这个方法来降低复杂度。

代码:

#include <bits/stdc++.h>

using namespace std;

const int N_MAX = 501;
int n;
struct Mat {
  int mat[N_MAX][N_MAX];
  int N, M;
  bool operator ==(const Mat& rhs) const {
    for (int i = 1; i <= N; i++) {
      for (int j = 1; j <= M; j++) {
        if (mat[i][j] != rhs.mat[i][j]) return false;
      }
    }
    return true;
  }

  void init(int n, int m) {
    N = n;
    M = m;
  }
  void read() {
    for (int i = 1; i <= N; i++) {
      for (int j = 1; j <= N; j++) {
        scanf("%d", mat[i] + j);
      }
    }
  }

  void gen() {
    for (int i = N; i <= M; i++) {
      for (int j = 1; j <= M; j++) {
        mat[i][j] = rand() % 10 + 1;
      }
    }
  }
}arr[4];
Mat mul(const Mat& lhs, const Mat& rhs) {
  assert(lhs.M == rhs.N);
  Mat ret;
  ret.init(lhs.N, rhs.M);
  for (int i = 1; i <= lhs.N; i++) {
    for (int j = 1; j <= rhs.M; j++) {
      ret.mat[i][j] = 0;
      for (int k = 1; k <= lhs.M; k++) {
        ret.mat[i][j] += lhs.mat[i][k] * rhs.mat[k][j];
      }
    }
  }
  return ret;
}
const double lim = 0.7;

inline bool check() {
  return mul(mul(arr[3], arr[0]), arr[1]) == mul(arr[3], arr[2]);
}
int main() {
  srand(time(0));
  scanf("%d", &n);
  for (int i = 0; i < 3; i++) {
    arr[i].init(n, n);
    arr[i].read();
  }
  arr[3].init(1, n);
  while (double(clock()) / CLOCKS_PER_SEC < lim) {
    arr[3].gen();
    if (!check()) {
      puts("No");
      return 0;
    }
  }
  puts("Yes");
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值