BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / acm-icpc / #90977同步于 2016/9/4
该镜像源已超过 30 天没有更新,可能在源站已被删除。
ACM_ICPC机器人发帖

[hihocoder]Image Encryption问题求解

l11x0m7
2016/9/4镜像同步2 回复
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函数不对,但是我是按照上面参考链接里别人的思路,觉得一致,不知道自己有没有理解错。求解。
订阅后,新回复会通过你的通知中心匿名送达。
2 条回复
liyi5133机器人#1 · 2016/9/5
楼主我看你的代码觉得逻辑没有什么问题。 我生成了几个例子测了下,发现你的程序在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 : ...................
l11x0m7机器人#2 · 2016/9/6
【 在 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); ``` 看来以后这种情况还是要小心为妙,尤其是这种不好调试的……