题目描述
尺寸为N×N(1 <= N <= 10)个黑色和白色方块的正方形图案被转换为另一个正方形图案。 编写一个程序,它将识别已经应用于原始模式的最小变换,给出以下可能的转换列表:
•#1:90度旋转:图案顺时针旋转90度。
•#2:180度旋转:图案旋转顺时针旋转180度。
•#3:270度旋转:图案顺时针旋转270度。
•#4:反射:图案被水平反射(通过在图像中间的垂直线反射而变成自身的镜像)。
•#5:组合:图案水平反射,然后进行旋转之一(#1-#3)。
•#6:无更改:原始图案未更改。
•#7:变换无效:以上任何一种方法均未获得新模式。
在可以使用多个变换的情况下,选择最小数目以上的变换。
程序名称:transform
输入格式
第1行:单个整数,N
行2..N + 1:N行N个字符(每个都有“@”或“ - ”); 这是转型前的广场
行N + 2..2 * N + 1:N个字符的N行(每个都是“@”或“ - ”); 这是转型后的广场
输入(file transform.in)
3
@-@
---
@@-
@-@
@--
--@
输出格式
包含从1到7(如上所述)的数字的单行,将从“before”表示更改为“after”表示形式所需的转换进行分类。
输出(file transform.out)
1
解题思路
本题主要思想是,根据题目已知前4种变换是基本变换(同时我们能表示出来),因此我们把原矩阵经过前4种变换中的任意一种后的矩阵与结果矩阵进行比较,若相等则输出变换名称;而第5种变换是基于前4种变换的它包括一个变化4和其他另外一种(变换1~3),因此我们把变换4与变换1~3中任意一个搭配的变换后的矩阵与结果矩阵进行比较,若想等则输出变换名称5;一开始若原矩阵和结果矩阵相等直接输出变换名称6;否则输出变换名称7.
此题关键看懂题目,它是要在1~7当中选择一个,而不是搭配,同时,各种转换的规律也要清楚。
解题代码
/*
ID:15189822
PROG:transform
LANG:C++
*/
#include<iostream>
#include<cstdio>
#include<fstream>
using namespace std;
ofstream fout("transform.out");
ifstream fin("transform.in");
int n;
typedef struct board{
char v[11][11];
}Board;
Board a,b;
Board rdboard(int n){
Board c;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
fin>>c.v[i][j];
}
//fin>>endl;
}
return c;
}
Board change(Board a,int k,int n){//前四种变换
Board c;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
switch(k){
case 1: c.v[i][j]=a.v[n-j+1][i];break;
case 2: c.v[i][j]=a.v[n+1-i][n+1-j];break;
case 3: c.v[i][j]=a.v[j][n+1-i];break;
case 4: c.v[i][j]=a.v[i][n+1-j];break;
}
}
}
return c;
}
int isequel(Board a,Board b,int n){//判断a与b是否相等相等返回1,否则返回0
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(a.v[i][j]!=b.v[i][j]) return 0;
}
}
return 1;
}
int main(){
fin>>n;
a=rdboard(n);
b=rdboard(n);
for(int i=1;i<=4;i++){
Board t=change(a,i,n);
if(isequel(t,b,n)){
fout<<i<<endl;
return 0;
}
if(i==4){
for(int j=1;j<=3;j++){
if(isequel(change(t,j,n),b,n)){
fout<<"5"<<endl;
return 0;
}
}
}
}
if(isequel(a,b,n)){
fout<<"6"<<endl;
return 0;
}
fout<<"7"<<endl;
return 0;
}