#1240 : Image Encryption
-
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
样例输出 -
Yes No Yes
这道题可以用最小表示法去做,就是把两个矩阵都表示成其最小表示矩阵。判断它们的最小矩阵是否一样即可。我们可以定义最小表示矩阵:对于两个数字矩阵A,
B
,我们从上至下、从左至右逐个元素比较。若存在一个A(i,j)<B(i,j)
,则我们认为 A<B。例如下面两个例子,右边的数字矩阵就为左边矩阵的最小表示:
3 1 1 4 2 4 ====> 3 2 3 1 3 2 1 2 1 2 2 4 1 4 4 3 3 4 2 4 1 2 ====> 1 3 1 4 1 3 4 3 4 2 3 2
所以这道题的难点就转化成怎么表示其最小表示矩阵。我们可以通过dfs,将矩阵分割成最小(k*k,k为奇数),然后求该矩阵的最小表示。因为此时的矩阵
已经分割为最小,所以只用转3次然后取最小的即可。然后回溯上去。
还有一个要注意的地方,将矩阵分为4块,然后分别求出最小表示矩阵后,如A(1) | A(2) matrix = ----------- A(4) | A(3)
此时这个矩阵由4个小矩阵构成,此时该矩阵的最小表示为下面四种的一种(而不是对这个矩阵进行旋转,然后取最小)
A(4)|A(1) A(3)|A(4) A(2)|A(3) A(1)|A(2) matrix = ----------- matrix= ----------- matrix= --------- matrix= -------------- A(3)|A(2) A(2)|A(1) A(1)|A(4) A(4)|A(3)
描述
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 separately 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 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
输出
For each testcase output Yes or No according to whether it is possible that B is encrypted from A.
using namespace std;
int a[105][105],b[105][105];
int Min[105][105],now[105][105];
int temp[105][105];
void rotate(int t[105][105],int n,int starti,int startj)
{
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
temp[i+starti][j+startj]=t[starti+n-1-j][startj+i];
}
}
for(int i=starti;i<=n+starti-1;i++)
{
for(int j=startj;j<=n+startj-1;j++)
{
t[i][j]=temp[i][j];
}
}
}
bool cmp(int s[105][105],int x[105][105],int n,int starti,int startj)
{
for(int i=starti;i<=n+starti-1;i++)
{
for(int j=startj;j<=n+startj-1;j++)
{
if(x[i][j]<s[i][j])
return true;
else if(x[i][j]>s[i][j])
return false;
}
}
return false;
}
void matrix_rotate(int s[105][105],int n,int starti,int startj)
{
int temp;
for(int i=starti;i<=n/2+starti-1;i++)
{
for(int j=startj;j<=n/2+startj-1;j++)
{
temp=s[i][j];
s[i][j]=s[i][j+n/2];
s[i][j+n/2]=temp;
}
}
for(int i=starti;i<=n/2+starti-1;i++)
{
for(int j=startj+n/2;j<=n+startj-1;j++)
{
temp=s[i][j];
s[i][j]=s[i+n/2][j];
s[i+n/2][j]=temp;
}
}
for(int i=starti+n/2;i<=n+starti-1;i++)
{
for(int j=startj+n/2;j<=n+startj-1;j++)
{
temp=s[i][j];
s[i][j]=s[i][j-n/2];
s[i][j-n/2]=temp;
}
}
}
void change(int x[105][105],int n,int starti,int startj)
{
if(n%2!=0)
{
for(int i=starti;i<=n+starti-1;i++)
{
for(int j=startj;j<=n+startj-1;j++)
{
Min[i][j]=x[i][j];
now[i][j]=x[i][j];
}
}
for(int i=1;i<=3;i++)
{
rotate(now,n,starti,startj);
if(cmp(Min,now,n,starti,startj))
{
for(int i=starti;i<=starti+n-1;i++)
{
for(int j=startj;j<=n+startj-1;j++)
{
Min[i][j]=now[i][j];
}
}
}
}
for(int i=starti;i<=n+starti-1;i++)
{
for(int j=startj;j<=n+startj-1;j++)
{
x[i][j]=Min[i][j];
}
}
}
else
{
change(x,n/2,starti,startj);
change(x,n/2,starti,startj+n/2);
change(x,n/2,starti+n/2,startj);
change(x,n/2,starti+n/2,startj+n/2);
for(int i=starti;i<=n+starti-1;i++)
{
for(int j=startj;j<=n+startj-1;j++)
{
Min[i][j]=x[i][j];
now[i][j]=x[i][j];
}
}
for(int i=1;i<=3;i++)
{
matrix_rotate(now,n,starti,startj);
if(cmp(Min,now,n,starti,startj))
{
for(int i=starti;i<=n+starti-1;i++)
{
for(int j=startj;j<=n+startj-1;j++)
{
Min[i][j]=now[i][j];
}
}
}
}
for(int i=starti;i<=n+starti-1;i++)
{
for(int j=startj;j<=n+startj-1;j++)
{
x[i][j]=Min[i][j];
}
}
}
}
int main()
{
int cas;
scanf("%d",&cas);
while(cas--)
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
cin>>a[i][j];
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
cin>>b[i][j];
}
}
change(a,n,1,1);
change(b,n,1,1);
int flag=1;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(a[i][j]!=b[i][j])
{
flag=0;
break;
}
}
}
if(flag==0)
{
cout<<"No"<<endl;
}
else
{
cout<<"Yes"<<endl;
}
}
}