1. 程式人生 > 實用技巧 >B-矩陣

B-矩陣

描述

給出了兩個矩陣 A和B ,每個矩陣的大小為 n×m。 你可以執行以下操作來對 AA 進行無限次矩陣處理:
取 A 的任何平方正方形子矩陣並將其轉置(即子矩陣的第 i 行和第 j 列中的子矩陣元素在轉置後將位於第 j 行和第 i 列中,並且轉置子矩陣本身將保留在矩陣 A )中的位置。 你的的任務是檢查是否有可能將矩陣 A 轉換為矩陣 B 。
操作例項
矩陣 M 的平方正方形子矩陣是 M 裡的一個正方形矩陣(正方形矩陣的所有元素,如圖綠色部分所示),正方形矩陣的邊長 k 可以是 1≤k≤min(n,m)

輸入

第一行一個 T ,表示測試用例個數。
對於每個測試用例,第一行包含兩個整數 n 和 m ,它們之間用空格隔開-分別是 A 和 B 中的行數和列數。
接下來的 n 行中的每行包含 m 個整數,這些行的第 i 行中的第 j 個數字表示矩陣 A 的第 i 行的第 j 個元素。
接下來的 n 行中的每行包含 m 個整數,這些行的第 i 行中的第 j 個數字表示矩陣 B 的第 i 行的第 j 個元素。

輸出

一共 T 行。
對於每個測試用例,如果可以將 A 轉換為 B ,則列印“ YES”(不帶引號),否則可以列印“ NO”(不帶引號)。

樣例

1
2 2
1 1
6 1
1 6
1 1
YES
2
2 2
4 4
4 5
5 4
4 4
3 3
1 2 3
4 5 6
7 8 9
1 4 7
2 5 6
3 8 9
NO
YES

提示

對於 10% 的資料:
1≤T≤2,1≤n,m≤2,1≤A{i,j}≤10^3,1≤B{i,j}≤10^3,∑n≤2,∑m≤2
對於 100% 的資料:
1≤T≤500,1≤n,m≤500, 1≤A{ij}≤10^9,1≤B{ij}≤10^9,∑n≤500,∑m≤500

CODE

AC程式碼

#include <bits/stdc++.h>
using namespace std;
#define rep(a, b, c) for(int a = b; a <= c; a++)
#define dep(a, b, c) for(int a = b; a >= c; a--)

int t, n, m, mpa[501][501], mpb[501][501];

int main(){
	scanf("%d", &t);
	while(t--){
		scanf("%d%d", &n, &m);
		rep(i, 1, n){
			rep(j, 1, m){
				scanf("%d", &mpa[i][j]);
			} 
		} 
		rep(i, 1, n){
			rep(j, 1, m){
				scanf("%d", &mpb[i][j]);
			}
		}
		int x, y, ppp = 0;
		rep(i, 1, n){//行為起點的對角線列舉 
			map<char, int> mp;  
			x = 0; y = i + 1;
			int len = i;
			rep(j, 1, len){
				x++; y--;
				mp[(char)(mpa[x][y] - '0')]++;
			} 
			x = 0; y = i + 1; 
			rep(j, 1, len){
				x++; y--;
				if(mpa[x][y] == mpb[x][y]){
					mp[(char)(mpa[x][y] - '0')]--;
					continue;
				} 
				int xx = 0, yy = i + 1, p = 0;
				rep(k, 1, len){
					xx++; yy--;
					if(mp[(char)(mpa[x][y] - '0')] && mpa[x][y] == mpb[xx][yy]){
						mp[(char)(mpa[x][y] - '0')]--;
						p = 1;
						break; 
					}
				}
				if(!p){
					ppp = 1;
					printf("NO\n");
					break;
				}
				
			}
			if(ppp){
				break;
			}
		} 
		if(!ppp)
			printf("YES\n");
	}
	return 0;
}