写了时间复杂度较小的解法。简单来说,就是把两张图像分别变换成它们的“规范型”。然后,通过比较它们的“规范型”是否相同,来判断两张图像是否可以相互变换。
首先,是把二维的图像数据(Matrix)变换成一维的数组(Stream),以便对其进行旋转。Stream是以旋转的方式排列数据,因而对其进行旋转操作,非常方便和高效。
然后,就是把Stream转换成它的“规范型”(其实就是所有可能的变换结果中字典序最小的变换结果)。具体来说,就是,先把四个子Stream变换成“规范型”,再把它整体进行旋转操作,在所得的四个操作结果中选字典序最小的操作结果作为它的“规范型”。
最后,比较它们的“规范型”,完全相同输出“Yes”,否则,输出“No”。
时间复杂度应该是O(N^2 log N)吧。N是图像边长。
#include <stdio.h>
int N;
struct Pair {
int x, y;
Pair() : x(0), y(0) {}
Pair(int x, int y) : x(x), y(y) {}
Pair operator + (const Pair & t) const {
return Pair(x + t.x, y + t.y);
}
Pair operator * (const Pair & t) const {
return Pair(x * t.x - y * t.y, y * t.x + x * t.y);
}
Pair & operator += (const Pair & t) {
return (*this = *this + t);
}
Pair & operator *= (const Pair & t) {
return (*this = *this * t);
}
};
struct Matrix {
int n;
int e[105][105];
int operator [] (const Pair & p) const {
return e[p.y][p.x];
}
} mA, mB;
struct Stream {
int n;
int e[105 * 105];
void initialize(const Matrix & A, Pair Org, Pair V, int M, int N) {
if(M != N) {
Pair I;
for(I.x = 0; I.x < M; ++I.x)
for(I.y = 0; I.y < N; ++I.y)
e[n++] = A[Org + I * V];
return;
}
if(N & 1) {
e[n++] = A[Org + Pair(N>>1, N>>1) * V];
int i; Pair I(0, 1);
for(i=0; i<4; ++i) {
initialize(A, Org, V, (N>>1)+1, N>>1);
Org += Pair(N-1, 0) * V;
V *= I;
}
return;
}
int i; Pair I(0, 1);
for(i=0; i<4; ++i) {
initialize(A, Org, V, N>>1, N>>1);
Org += Pair(N-1, 0) * V;
V *= I;
}
}
void initialize(const Matrix & A) {
n = 0;
initialize(A, Pair(0, 0), Pair(1, 0), A.n, A.n);
}
int t[105 * 105];
void rotate(int i, int n, int k) {
if(n & 3) {
t[i] = e[i];
++i;
--n;
}
int j;
for(j=0; j<n; ++j)
t[i + (j + (n>>2) * k) % n] = e[i + j];
}
int kk, tt[105 * 105];
void regulate(int i, int n) {
int j, k;
if((n & 3) == 0) {
for(j=0; j<4; ++j)
regulate(i + (n>>2) * j, n>>2);
}
kk = 0;
for(j=i; j<i+n; ++j) tt[j] = e[j];
for(k=1; k<4; ++k) {
rotate(i, n, k);
for(j=i; j < i+n && t[j] == tt[j]; ++j);
if(j < i+n && t[j] < tt[j]) {
kk = k;
for(j=i; j<i+n; ++j) tt[j] = t[j];
}
}
for(j=i; j<i+n; ++j) e[j] = tt[j];
}
void regulate() {
regulate(0, n);
}
} sA, sB;
int main() {
int T;
scanf("%d", &T);
int i, j, k;
for(i=0; i<T; ++i) {
scanf("%d", &N);
mA.n = N;
for(j=0; j<N; ++j)
for(k=0; k<N; ++k)
scanf("%d", &mA.e[j][k]);
mB.n = N;
for(j=0; j<N; ++j)
for(k=0; k<N; ++k)
scanf("%d", &mB.e[j][k]);
sA.initialize(mA);
sB.initialize(mB);
sA.regulate();
sB.regulate();
for(j=0; j<N*N && sA.e[j]==sB.e[j]; ++j);
if(j == N*N) printf("Yes\n");
else printf("No\n");
}
return 0;
}