返回信息流Time Limit:10000ms
Case Time Limit:1000ms
Memory Limit:256MB
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.
原题:http://hihocoder.com/problemset/problem/1240
思路参考:http://hihocoder.com/discuss/question/3663
我的代码:
```
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int t, n;
struct point{
int x, y;
point(int x, int y){
this->x = x;
this->y = y;
}
};
void myswap(vector< vector<int> >& res, point p1, point p2, int N){
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
swap(res[i+p1.x][j+p1.y], res[i+p2.x][j+p2.y]);
}
vector< vector<int> >& rotate_mat(vector< vector<int> >& res, int N){
// vector< vector<int> > ret(N, vector<int>(N, 0));
myswap(res, point(0, 0), point(0, N), N);
myswap(res, point(0, 0), point(N, 0), N);
myswap(res, point(N, 0), point(N, N), N);
return res;
}
vector< vector<int> > rotate(vector< vector<int> >& res, int N){
vector< vector<int> > ret(N, vector<int>(N, 0));
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
ret[j][N-i-1] = res[i][j];
}
}
return ret;
}
bool comp(vector< vector<int> >& f, vector< vector<int> >& t, int N){
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
if(f[i][j]<t[i][j])
return true;
else if(f[i][j]>t[i][j])
return false;
}
}
return false;
}
void dfs(vector< vector<int> >& res, int N, int i, int j){
if(N%2==0){
dfs(res, N/2, 0, 0);
dfs(res, N/2, 0, N/2);
dfs(res, N/2, N/2, 0);
dfs(res, N/2, N/2, N/2);
}
vector< vector<int> > min(N, vector<int>(N, 0));
vector< vector<int> > tp(N, vector<int>(N, 0));
for(int row=i;row<i+N;row++)
for(int col=j;col<j+N;col++){
min[row-i][col-j] = res[row][col];
tp[row-i][col-j] = res[row][col];
}
for(int k=0;k<3;k++){
if(N%2==0)
tp = rotate_mat(tp, N/2);
else
tp = rotate(tp, N);
if(comp(tp, min, N))
min = tp;
}
for(int row=i;row<i+N;row++)
for(int col=j;col<j+N;col++)
res[row][col] = min[row-i][col-j];
}
int main(){
while(cin>>t){
while(t--){
cin>>n;
vector< vector<int> > A(n, vector<int>(n, 0)), B(n, vector<int>(n, 0));
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
cin>>A[i][j];
}
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
cin>>B[i][j];
}
}
// cout<<"->>>>>>>>1"<<endl;
dfs(A, n, 0, 0);
dfs(B, n, 0, 0);
// cout<<"->>>>>>>>2"<<endl;
int i, j;
for(i=0;i<n;i++){
for(j=0;j<n;j++){
if(A[i][j]!=B[i][j]){
cout<<"No"<<endl;
break;
}
}
if(j!=n)
break;
}
if(i==n)
cout<<"Yes"<<endl;
}
}
}```
返回WA,有人说是comp函数不对,但是我是按照上面参考链接里别人的思路,觉得一致,不知道自己有没有理解错。求解。
这是一条镜像帖。来源:北邮人论坛 / acm-icpc / #90977同步于 2016/9/4
该镜像源已超过 30 天没有更新,可能在源站已被删除。
ACM_ICPC机器人发帖
[hihocoder]Image Encryption问题求解
l11x0m7
2016/9/4镜像同步2 回复
订阅后,新回复会通过你的通知中心匿名送达。
2 条回复
楼主我看你的代码觉得逻辑没有什么问题。
我生成了几个例子测了下,发现你的程序在N为4(不包含4)的倍数的时候结果是错的
比如8x8,12x12,16x16,20x20,而之间的其他偶数6、10、12都没问题
不知道这个线索能不能发现点什么,比如多次调用了块的旋转会出问题?要不要检查一下传递和还原?下面是一个例子:
```
8
7 8 5 6 6 5 6 5
7 8 5 6 6 5 6 5
7 8 5 6 7 7 7 8
7 8 5 6 8 8 7 8
1 1 2 1 1 1 3 4
2 2 2 1 2 2 3 4
3 3 4 4 2 2 3 3
4 4 3 3 1 1 4 4
8 7 5 5 7 8 8 8
8 7 6 6 7 8 7 7
7 8 5 6 6 6 6 5
7 8 5 6 5 5 6 5
2 1 4 4 3 3 2 2
2 1 3 3 4 4 1 1
1 2 4 4 3 4 1 2
1 2 3 3 3 4 1 2
```
应该是yes,你的输出的no
【 在 l11x0m7 的大作中提到: 】
: Time Limit:10000ms
: Case Time Limit:1000ms
: Memory Limit:256MB
: ...................
【 在 liyi5133 的大作中提到: 】
: [md]
: 楼主我看你的代码觉得逻辑没有什么问题。
: 我生成了几个例子测了下,发现你的程序在N为4(不包含4)的倍数的时候结果是错的
: ...................
感谢你的热情解答。我发现问题在于递归的时候坐标的偏移没有写对。
原来:
```
dfs(res, N/2, 0, 0);
dfs(res, N/2, 0, N/2);
dfs(res, N/2, N/2, 0);
dfs(res, N/2, N/2, N/2);
```
现在:
```
dfs(res, N/2, i, j);
dfs(res, N/2, i, j+N/2);
dfs(res, N/2, i+N/2, j);
dfs(res, N/2, i+N/2, j+N/2);
```
看来以后这种情况还是要小心为妙,尤其是这种不好调试的……