图案变换问题(湖南省首届“湘邮科技杯”大学生程序设计大赛试题)
图案变换问题
时间限制(普通/Java):1000MS/3000MS 运行内存限制:65536KByte
描述
给出一个正方形图案和它的变换图案,称为图案变换对。编写程序,求图案变换对之间的最小变换。图案是由黑白两种小方块构成的。可能的变换包括:
(1) 旋转 90 度:图案顺时针旋转 90 度,记做 rot90
(2) 旋转 180 度:图案顺时针旋转 180 度,记做 rot180
(3) 旋转 270 度:图案顺时针旋转 270 度,记做 rot270
(4) 竖直映像:图案以其上方的一条平行线为轴翻转,记做 vr
(5) 联合变换:图案首先做一次竖直映像变换,然后做一次旋转变换,记做 vr-rot90 或 vr-rot180 或vr-rot270
(6) 保持:图案和变换后的图案完全一样,记做 idt
(7) 错误:无法应用上述变换将初始图案变换成它的变换图案,记做 imp
输入
输入文件中包含多组图案变换对。每一对图案数据的起始行都是一个整数,表示正方形图案的边长 a(以一个小方块为单位,1<=a<=100) ,后续的 a 行,每一行包含了原图案的一行和变换图案的对应行,两者之间用一个空格分开。黑色小方块用 b 表示,白色小方块用 o 表示。
输出
输出文件的每一行对应输入文件的每一个图案变换对。其中每行开始的整数表示对应图案对在输入文件中出现的序号,紧跟一个空格,然后就是该图案对的最小变换,采用上述记号表示。
备注:为了比较不同变换的大小,定义:旋转变换的代价小于映像变换,小角度旋转变换的代价小于大角度旋转变换,保持变换的代价最小。注意:对本题而言,只有上面列出的变换是合法的,如果某个图案对可以由多个变换得到,则应选择代价最小的变换。
样例输入
5
booob oooob
obooo ooobo
ooobo obooo
oobob ooboo
oooob bboob
6
oooobb boooob
oooboo bobooo
bboobo oboobo
oobooo ooobob
oooboo oobooo
ooboob oobooo
2
bo bo
ob ob
4
oobo ooob
bboo oooo
oooo bboo
ooob oobo
5
boooo obooo
obooo ooboo
obooo ooboo
ooobo oooob
oooob boooo
4
oboo oobo
obob booo
oooo oobb
oobo oooo
2
oo bb
bb oo
样例输出
1 rot90
2 rot270
3 idt
4 vr
5 imp
6 vr-rot270
7 rot180
题解:只要根据旋转的特点来找到坐标的规律即可。
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; int n; char str[110][110],op[110][110]; int idt() // 完全一样 { for(int i=0; i<n; i++) for(int j=0; j<n; j++) if(str[i][j]!=op[i][j]) return 0; return 1; } int rot90() //顺时针旋转90度 { for(int i=0; i<n; i++) for(int j=0; j<n; j++) if(str[i][j]!=op[j][n-i-1]) return 0; return 1; } int rot180() //顺时针旋转180度 { for(int i=0; i<n; i++) for(int j=0; j<n; j++) if(str[i][j]!=op[n-i-1][n-j-1]) return 0; return 1; } int rot270() //顺时针旋转270度 { for(int i=0; i<n; i++) for(int j=0; j<n; j++) if(str[i][j]!=op[n-j-1][i]) return 0; return 1; } int vr() //竖直映像 { for(int i=0; i<n; i++) for(int j=0; j<n; j++) if(str[i][j]!=op[n-i-1][j]) return 0; return 1; } int vr_rot90() { for(int i=0; i<n; i++) for(int j=0; j<n; j++) if(str[i][j]!=op[j][i]) return 0; return 1; } int vr_rot180() { for(int i=0; i<n; i++) for(int j=0; j<n; j++) if(str[i][j]!=op[i][n-j-1]) return 0; return 1; } int vr_rot270() { for(int i=0; i<n; i++) for(int j=0; j<n; j++) if(str[i][j]!=op[n-j-1][n-i-1]) return 0; return 1; } int main() { int ans=1; while(~scanf("%d",&n)) { for(int i=0; i<n; i++) { scanf("%s",str[i]); scanf("%s",op[i]); } printf("%d ",ans++); if(idt()) { printf("idt\n"); continue; } if(rot90()) { printf("rot90\n"); continue; } if(rot180()) { printf("rot180\n"); continue; } if(rot270()) { printf("rot270\n"); continue; } if(vr()) { printf("vr\n"); continue; } if(vr_rot90()) { printf("vr-rot90\n"); continue; } if(vr_rot180()) { printf("vr-rot180\n"); continue; } if(vr_rot270()) { printf("vr-rot270\n"); continue; } printf("imp\n"); } return 0; }