• 【bzoj2396】神奇的矩阵 随机化


    题目描述

    给出三个行数和列数均为N的矩阵A、B、C,判断A*B=C是否成立。

    输入

    题目可能包含若干组数据。
    对于每组数据,第一行一个数N,接下来给出三个N*N的矩阵,依次为A、B、C三个矩阵。

    输出

    对于每组数据,若A*B=C成立,则输出Yes,否则No。每个答案占一行。

    样例输入

    1
    2
    2
    100

    样例输出

    No


    题解

    随机化

    如果直接把$A$与$B$的乘积算出来肯定会GG。。

    考虑,如果$A*B=C$,那么$T*(A*B)=T*C$,而矩阵乘法具有结合律,因此有$(T*A)*B=T*C$。如果取$T$为$1*n$的行向量,那么每一步矩阵乘法的复杂度都是$O(n^2)$的。

    于是可以使用这种方法大致判断出$A*B$是否等于$C$。随机出$T$矩阵,然后判断$(T*A)*B$与$T*C$是否相等即可。大约每组数据随机10次即可出解。

    #include <cstdio>
    #include <algorithm>
    #define N 1010
    using namespace std;
    typedef long long ll;
    ll a[N][N] , b[N][N] , c[N][N] , t[N] , v[N];
    bool judge(int n)
    {
    	int cnt , i , j;
    	ll sb , sc;
    	for(cnt = 1 ; cnt <= 10 ; cnt ++ )
    	{
    		for(i = 1 ; i <= n ; i ++ ) t[i] = rand() % 999 + 1;
    		for(i = 1 ; i <= n ; i ++ )
    			for(v[i] = 0 , j = 1 ; j <= n ; j ++ )
    				v[i] += t[j] * a[j][i];
    		for(i = 1 ; i <= n ; i ++ )
    		{
    			for(sb = sc = 0 , j = 1 ; j <= n ; j ++ )
    				sb += v[j] * b[j][i] , sc += t[j] * c[j][i];
    			if(sb != sc) return 0;
    		}
    	}
    	return 1;
    }
    int main()
    {
    	srand(20011011);
    	int n , i , j;
    	while(~scanf("%d" , &n))
    	{
    		for(i = 1 ; i <= n ; i ++ )
    			for(j = 1 ; j <= n ; j ++ )
    				scanf("%lld" , &a[i][j]);
    		for(i = 1 ; i <= n ; i ++ )
    			for(j = 1 ; j <= n ; j ++ )
    				scanf("%lld" , &b[i][j]);
    		for(i = 1 ; i <= n ; i ++ )
    			for(j = 1 ; j <= n ; j ++ )
    				scanf("%lld" , &c[i][j]);
    		if(judge(n)) puts("Yes");
    		else puts("No");
    	}
    	return 0;
    }
    

     

  • 相关阅读:
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    网上怎么赚钱?如何利用CPA赚钱?
    在农村养殖什么赚钱?要做好哪些预防工作?
    计算机组成的基本硬件设备
    JAVA回溯法求0-1背包
    TensorFlow学习笔记之批归一化:tf.layers.batch_normalization()函数
    数据库连接池的大小值设定,不能随意设置太大的值
    N皇后问题
    19个强大、有趣、又好玩的 Linux 命令!
    JAVA马的遍历
  • 原文地址:https://www.cnblogs.com/GXZlegend/p/7522542.html
Copyright © 2020-2023  润新知