• Gym


    题意:给出N,以及三个矩阵A,B,C,大小都为N*N。问是否满足A*B=C; N<1000;

    思路:由于矩阵乘法的复杂度为O(N^3);而部分验证又不能保证结果正确。我们巧妙地利用矩阵乘法的结合律:使其变为1*N和N*N的矩阵乘法,使复杂度降低为O(N^2); 即随机构造矩阵X(1*N),Y(N*1),那么问题成为验证X*A*B*Y==X*C*Y?然后利用结合律即可验证。

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int maxn=1010;
    const int Mod=1e9+7;
    int a[maxn][maxn],b[maxn][maxn],c[maxn][maxn];
    int r1[maxn],r2[maxn],x1[maxn],x2[maxn],yy1[maxn],ans1,ans2;
    int main()
    {
        int T=10,N,i,j;
        scanf("%d",&N);
        for(i=1;i<=N;i++) for(j=1;j<=N;j++) scanf("%d",&a[i][j]);
        for(i=1;i<=N;i++) for(j=1;j<=N;j++) scanf("%d",&b[i][j]);
        for(i=1;i<=N;i++) for(j=1;j<=N;j++) scanf("%d",&c[i][j]);
        while(T--){
            for(i=1;i<=N;i++) r1[i]=rand()%Mod; //1*N 
            for(i=1;i<=N;i++) r2[i]=rand()%Mod; //N*1 
            for(i=1;i<=N;i++) x1[i]=x2[i]=yy1[i]=0;
            ans1=ans2=0;
            for(i=1;i<=N;i++)     //1*N  N*N N*N N*1=(1*N)*(N*1)
             for(j=1;j<=N;j++)
              (x1[i]+=(ll)r1[j]*a[j][i]%Mod)%=Mod;
            for(i=1;i<=N;i++)
             for(j=1;j<=N;j++)
              (x2[i]+=(ll)b[i][j]*r2[j]%Mod)%=Mod;
            for(i=1;i<=N;i++) (ans1+=(ll)x1[i]*x2[i]%Mod)%=Mod;
            
            for(i=1;i<=N;i++)    //1*N N*N N*1 =(1*N)*(N*1)
             for(j=1;j<=N;j++)
              (yy1[i]+=(ll)r1[j]*c[j][i]%Mod)%=Mod;
            for(i=1;i<=N;i++) (ans2+=(ll)yy1[i]*r2[i]%Mod)%=Mod;
            if(ans1!=ans2){ puts("NO"); return 0; }
        }
        puts("YES"); return 0;
    }
  • 相关阅读:
    Simple DirectMedia Layer常用API总结
    [游戏复刻] Super Mario Brothers(1985. Famicom)
    [游戏复刻] 2048(2014. Android)
    图的结构以及寻路算法的c实现
    散列查找的C实现
    【游戏编程从0开始】一、基本结构
    C++中const关键字用法总结
    C标准库常用函数概要
    字符串表达式计算器的设计
    初探数据结构
  • 原文地址:https://www.cnblogs.com/hua-dong/p/9226341.html
Copyright © 2020-2023  润新知