题目描述
一块 n × n n \times n n×n 正方形的黑白瓦片的图案要被转换成新的正方形图案。写一个程序来找出将原始图案按照以下列转换方法转换成新图案的最小方式:
- 转 90 ° 90\degree 90°:图案按顺时针转 90 ° 90\degree 90°。
- 转 180 ° 180\degree 180°:图案按顺时针转 180 ° 180\degree 180°。
- 转 270 ° 270\degree 270°:图案按顺时针转 270 ° 270\degree 270°。
- 反射:图案在水平方向翻转(以中央铅垂线为中心形成原图案的镜像)。
- 组合:图案在水平方向翻转,然后再按照 1 ∼ 3 1 \sim 3 1∼3 之间的一种再次转换。
- 不改变:原图案不改变。
- 无效转换:无法用以上方法得到新图案。
如果有多种可用的转换方法,请选择序号最小的那个。
只使用上述 7 7 7 个中的一个步骤来完成这次转换。
输入格式
第一行一个正整数 n n n。
然后
n
n
n 行,每行
n
n
n 个字符,全部为 @
或 -
,表示初始的正方形。
接下来
n
n
n 行,每行
n
n
n 个字符,全部为 @
或 -
,表示最终的正方形。
输出格式
单独的一行包括 1 ∼ 7 1 \sim 7 1∼7 之间的一个数字(在上文已描述)表明需要将转换前的正方形变为转换后的正方形的转换方法。
样例输入
3
@-@
---
@@-
@-@
@--
--@
样例输出
1
【数据范围】
对于
100
%
100\%
100% 的数据,
1
≤
n
≤
10
1\le n \le 10
1≤n≤10。
思路分析
本题就是用二维字符数组进行模拟。需要我们特别有耐心的解题。
顺时针旋转180°是2次顺时针旋转90°;顺时针旋转270°是3次顺时针旋转90°。所以,题目给的7个操作,可以被拆解成2个不同的操作:
a、顺时针旋转90°
b、反射
注意: 题目要求,有多种可用的转换方法时选择序号最小的那个。所以必须按1~7的操作顺序处理。
参考代码
#include <iostream>
#include <cstring> //memcpy(destination, source, num_bytes)
using namespace std;
const int N = 15;
char a[N][N],a1[N][N], b[N][N], t[N][N];
int n; //n一定要是全局变量,因为函数中要使用
//顺时针旋转90度
void rotate90() {
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
t[j][n - 1 - i] = a[i][j]; // 顺时钟旋转90°,结果存到数组t里
memcpy(a, t, sizeof(t)); // 替换原来的 a
}
//反射
void reflex() {
for (int i = 0; i < n; i++)
for (int j = 0; j < n / 2; j++)
swap(a[i][n - 1 - j], a[i][j]); // 图案在水平方向翻转
}
//比较a和b是否相等
bool equal() {
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
if (a[i][j] != b[i][j]) // 位置上某个字符不一样
return false;
return true; // 否则代表两个矩阵相等
}
//
int main() {
//读入两个正方形图案
cin >> n;
//读入a
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
cin >> a[i][j];
//读入b
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
cin >> b[i][j];
//先将a拷贝一份,因为题目要求“有多种可用的转换方法时选择序号最小的那个”,所以必须按顺序处理。
//前面处理的过程中会修改a,所以留个备份。
memcpy(a1,a,sizeof(a));
//判断
rotate90();
if (equal()) {// 顺时针旋转90°后相等
cout << 1;
return 0;
}
rotate90();
if (equal()) {// 顺时针旋转180°后相等
cout << 2;
return 0;
}
rotate90();
if (equal()) {//顺时针旋转270°后相等
cout << 3;
return 0;
}
memcpy(a,a1,sizeof(a)); //将a重置到初始状态
reflex(); //反射
if (equal()) {//反射后相等
cout << 4;
return 0;
}
//反射后,按1~3任一种旋转相等
for (int i = 0; i < 3; i++) {
rotate90();
if (equal()) {
cout << 5;
return 0;
}
}
memcpy(a,a1,sizeof(a)); //将a重置到初始状态
if (equal()) { // 初始状态就相等
cout << 6;
return 0;
}
//无效转换
cout << 7;
return 0;
}