Description
A fancy square image encryption algorithm works as follow:
0. consider the image as an N x N matrix
1. choose an integer k∈ {0, 1, 2, 3}
2. rotate the square image k * 90 degree clockwise
3. if N is odd stop the encryption process
4. if N is even split the image into four equal sub-squares whose length is N / 2 and encrypt them recursively starting from step 0
Apparently different choices of the k serie result in different encrypted images. Given two images A and B, your task is to find out whether it is POSSIBLE that B is encrypted from A. B is possibly encrypted from A if there is a choice of k serie that encrypt A into B.
Input
Input may contains multiple testcases.
The first line of the input contains an integer T(1 <= T <= 10) which is the number of testcases.
The first line of each testcase is an integer N, the length of the side of the images A and B.
The following N lines each contain N integers, indicating the image A.
The next following N lines each contain N integers, indicating the image B.
For 20% of the data, 1 <= n <= 15
For 100% of the data, 1 <= n <= 100, 0 <= Aij, Bij <= 100000000
Output
For each testcase output Yes or No according to whether it is possible that B is encrypted from A.
- Sample Input
-
3 2 1 2 3 4 3 1 4 2 2 1 2 4 3 3 1 4 2 4 4 1 2 3 1 2 3 4 2 3 4 1 3 4 1 2 3 4 4 1 2 3 1 2 1 4 4 3 2 1 3 2
- Sample Output
-
Yes No Yes
Solution:
1 #include <cstdlib> 2 #include <cstdio> 3 #include <vector> 4 using namespace std; 5 6 7 void rotateImg(vector<vector<int> > &A) { 8 9 int N = A.size(); 10 int r = N >> 1; 11 int c = (N + 1) >> 1; 12 for (int i = 0; i < r; ++i) { 13 for (int j = 0; j < c; ++j) { 14 int tmp = A[i][j]; 15 A[i][j] = A[N - 1 - j][i]; 16 A[N - 1 - j][i] = A[N - 1 - i][N - 1 - j]; 17 A[N - 1 - i][N - 1 - j] = A[j][N - 1 - i]; 18 A[j][N - 1 - i] = tmp; 19 } 20 } 21 22 } 23 24 bool isEqual(vector<vector<int> > A, vector<vector<int> > B) { 25 int N = A.size(); 26 for (int i = 0; i < N; ++i) { 27 for (int j = 0; j < N; ++j) { 28 if (A[i][j] != B[i][j]) return false; 29 } 30 } 31 return true; 32 } 33 34 vector<vector<int> > split(vector<vector<int> > A, int x, int y) { 35 int N = A.size() >> 1; 36 vector<vector<int> > v(N, vector<int>(N, 0)); 37 for (int i = 0; i < N; ++i) { 38 for (int j = 0; j < N; ++j) { 39 v[i][j] = A[i + x][j + y]; 40 } 41 } 42 return v; 43 } 44 45 bool isEncrypted(vector<vector<int> > A, vector<vector<int> > B) { 46 int N = A.size(); 47 if (N == 1) return A[0][0] == B[0][0]; 48 if (N & 0x01) { 49 vector<vector<int> > AA = A; 50 for (int k = 0; k < 4; ++k) { 51 if (isEqual(AA, B)) return true; 52 rotateImg(AA); 53 } 54 return false; 55 } 56 else { 57 int N_2 = N >> 1; 58 vector<vector<int> > AA = A; 59 int x[] = { 0, N_2, 0, N_2 }; 60 int y[] = { 0, 0, N_2, N_2 }; 61 for (int k = 0; k < 4; ++k) { 62 bool flag = true; 63 for (int kk = 0; kk < 4; ++kk) { 64 if (!isEncrypted(split(AA, x[kk], y[kk]), split(B, x[kk], y[kk]))) { 65 flag = false; 66 break; 67 } 68 } 69 if (flag) return true; 70 rotateImg(AA); 71 } 72 return false; 73 } 74 } 75 76 77 78 79 int main() { 80 int T; 81 scanf("%d", &T); 82 while (T--) { 83 int N; 84 scanf("%d", &N); 85 vector<vector<int> > A(N, vector<int>(N, 0)); 86 vector<vector<int> > B(N, vector<int>(N, 0)); 87 for (int i = 0; i < N; ++i) { 88 for (int j = 0; j < N; ++j) { 89 int v; 90 scanf("%d", &v); 91 A[i][j] = v; 92 } 93 } 94 95 for (int i = 0; i < N; ++i) { 96 for (int j = 0; j < N; ++j) { 97 int v; 98 scanf("%d", &v); 99 B[i][j] = v; 100 } 101 } 102 103 if (isEncrypted(A, B)) printf("Yes\n"); 104 else printf("No\n"); 105 } 106 }