首页 > 其他分享 >【SSL 1535】小罐跳舞(构造)

【SSL 1535】小罐跳舞(构造)

时间:2022-10-26 22:24:49浏览次数:70  
标签:matrix re int SSL 1535 小罐

小罐跳舞

题目链接:SSL 1535

题目大意

给你三个矩阵 A,B,C,要你判断 A*B=C 是否成立。

思路

如果直接暴力乘,我们的复杂度是 \(O(n^3)\),但是我们只允许 \(O(n^2)\) 的。

看看这个 \(n^3\) 如何构成,就是 \(A\) 的 \(n\),\(B\) 的 \(m\),\(A\) 的 \(m\)(也就是 \(B\) 的 \(n\))
那你会发现取决于这三个值,而且后面会保留的是前面两个。
考虑把其中一个变成 \(1\),但是显然不能直接变,因为你要乘啊,你总得是要乘的。
那你考虑乘完之后变成 \(1\) 出来,然后再跟另一个乘上。
那就相当于用一个 \(A*B*R=C*R\rightarrow A*B=C\)
那你就让 \(R\) 是一个 \(n\times 1\) 的矩阵即可,这个我们可以随机生成。

然后按上面的说法我们就要先乘 \(B*R\),再带上 \(A\),但是注意顺序不能错。
然后因为这个随机可能出事,我们得多随机几次重复验证。
(然后我的代码三次就会超时,不过两次也能过,听说一次都能如果随机好的话)

代码

#include<cstdio>
#include<cstdlib>
#define rr register
#define ll long long

using namespace std;

const int N = 1005;
struct matrix {
	ll n, m, a[N][N];
}A, B, C, tmp, R;
int n;

matrix operator *(matrix x, matrix y) {
	matrix re; re.n = x.n; re.m = y.m;
	for (rr int i = 1; i <= re.n; i++) for (rr int j = 1; j <= re.m; j++) re.a[i][j] = 0;
	for (rr int k = 1; k <= x.m; k++)
		for (rr int i = 1; i <= re.n; i++)
			for (rr int j = 1; j <= re.m; j++)
				re.a[i][j] += x.a[i][k] * y.a[k][j];
	return re;
}

bool operator !=(matrix x, matrix y) {
	if (x.n != y.n || x.m != y.m) return 1;
	for (rr int i = 1; i <= x.n; i++)
		for (rr int j = 1; j <= x.m; j++)
			if (x.a[i][j] != y.a[i][j]) return 1;
	return 0;
}

ll re, zf; char c;
ll read() {
	re = 0; zf = 1; c = getchar();
	while (c < '0' || c > '9') {
		if (c == '-') zf = -zf; c = getchar();
	}
	while (c >= '0' && c <= '9') {
		re = (re << 3) + (re << 1) + c - '0';
		c = getchar();
	}
	return re * zf;
}

int main() {
	freopen("transform.in", "r", stdin);
	freopen("transform.out", "w", stdout);
	
	srand(19491001);
	while (scanf("%d", &n) != EOF) {
		A.n = A.m = n;
		for (rr int i = 1; i <= n; i++)
			for (rr int j = 1; j <= n; j++)
				A.a[i][j] = read();
		B.n = B.m = n;
		for (rr int i = 1; i <= n; i++)
			for (rr int j = 1; j <= n; j++)
				B.a[i][j] = read();
		C.n = C.m = n;
		for (rr int i = 1; i <= n; i++)
			for (rr int j = 1; j <= n; j++)
				C.a[i][j] = read();
		bool sam = 1;
		for (int tim = 1; tim <= 2; tim++) {
			R.n = n; R.m = 1; for (rr int i = 1; i <= n; i++) R.a[i][1] = rand();
			tmp = B * R; tmp = A * tmp;
			if (tmp != (C * R)) {
				sam = 0; break;
			}
		}
		if (sam) printf("Yes\n");
			else printf("No\n");
	}
	
	return 0;
}

标签:matrix,re,int,SSL,1535,小罐
From: https://www.cnblogs.com/Sakura-TJH/p/SSL_1535.html

相关文章