一、题目描述
链接:https://www.acwing.com/problem/content/1346/
来源:ACwing
我们现在要将一个 N×N 大小的由黑白瓷砖构成的正方形图案转换为一个新的正方形图案。
共有 7 种转换方式如下:
- 90 度旋转:将图案顺时针旋转 90 度。
- 180 度旋转:将图案顺时针旋转 180 度。
- 270 度旋转:将图案顺时针旋转 270 度。
- 镜像:沿着图片的中间垂直线翻转图片,使其变为自身的镜像。
- 组合:先进行镜像转换,再按照 1∼3 中的一种方式进行转换。
- 不改变:保持原图案,不做任何改变。
- 无效转换:上述任何一种方式都无法得到新图案。
如果只允许使用上述方式中的一种进行图形转换,能否将原图案转换为新图案?
请你求出用哪种转换方式,可以得到新图案,输出这一方式的序号。
如果有多种方式可以满足条件,则输出序号较小的方式的序号。
当然,如果无法完成转换,只能输出方式 7 无效转换。
输入格式
第一行一个整数 N,表示正方形图案的大小。
接下来 N 行,每行包含 N 个字符(‘-’或‘@’),表示初始的正方形图案。
再接下来 N 行,每行包含 N 个字符(‘-’或‘@’),表示希望得到的新正方形图案。
输出格式
输出一个 1∼7 之间的整数,表示将原图案转换为新图案所使用的具体转换方式的序号。
数据范围
1 ≤ N ≤ 10
输入样例:
3
@-@
---
@@-
@-@
@--
--@
输出样例:
1
二、题解
数据量较少的一道题,可以使用粗暴的解法。
即:找出各种转化的规律,然后将转化后的方形与目标方形比对。若相同则返回true,不同返回false。注意判断的时候要依据其所给顺序。
各种转化的规律:
初始
1 2 3
4 5 6
7 8 9
顺时针90度
7 4 1
8 5 2
9 6 3
第n列变第n行,行数变列数掉个个儿
顺时针180度
9 8 7
6 5 4
3 2 1
行掉个个儿,列也掉个个儿
顺时针270度
3 6 9
2 5 8
1 4 7
第n行到第n列,列数变行数掉个个儿
镜像
3 2 1
6 5 4
9 8 7
行不变,列掉个个儿
三、AC代码
#include<iostream>
using namespace std;
int n;
const int maxn = 15;
char Block[maxn][maxn];
char Target[maxn][maxn];
int op();
bool op1(char block[][maxn],char target[][maxn]);
bool op2(char block[][maxn],char target[][maxn]);
bool op3(char block[][maxn],char target[][maxn]);
bool op4(char block[][maxn],char target[][maxn]);
bool op5(char block[][maxn],char target[][maxn]);
bool op6(char block[][maxn],char target[][maxn]);
int main()
{
cin >> n;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
cin >> Block[i][j];
}
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
cin >> Target[i][j];
}
}
cout << op() << endl;
system("pause");
return 0;
}
int op()
{
if (op1(Block,Target))
{
return 1;
}
if (op2(Block,Target))
{
return 2;
}
if (op3(Block,Target))
{
return 3;
}
if (op4(Block,Target))
{
return 4;
}
if (op5(Block,Target))
{
return 5;
}
if (op6(Block,Target))
{
return 6;
}
return 7;
}
bool op1(char block[][maxn],char target[][maxn])
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (block[i][j] != target[j][n - i - 1])
{
return false;
}
}
}
return true;
}
bool op2(char block[][maxn],char target[][maxn])
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (block[i][j] != target[n - i - 1][n - j - 1])
{
return false;
}
}
}
return true;
}
bool op3(char block[][maxn],char target[][maxn])
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (block[i][j] != target[n - j - 1][i])
{
return false;
}
}
}
return true;
}
bool op4(char block[][maxn],char target[][maxn])
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (block[i][j] != target[i][n - j - 1])
{
return false;
}
}
}
return true;
}
bool op5(char block[][maxn],char target[][maxn])
{
char Mirror[maxn][maxn];
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
Mirror[i][n - j - 1] = block[i][j];
}
}
if (op1(Mirror,Target))
{
return true;
}
if (op2(Mirror,Target))
{
return true;
}
if (op3(Mirror,Target))
{
return true;
}
return false;
}
bool op6(char block[][maxn],char target[][maxn])
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (block[i][j] != target[i][j])
{
return false;
}
}
}
return true;
}
关于这道题,我的代码很容易理解,但是有些冗长。
转化的过程有的是可以省略掉的,比如90度,180度,270度,后者是前者转90度的结果,其实写一个90度旋转的函数就够用了。
如果我的题解对您有帮助,还望您不吝点赞。
欢迎讨论交流,期待共同进步!