给定两个 N×N的由字符 X
和 O
构成的字符矩阵。
你可以对第一个矩阵进行任意次(也可以不进行)旋转和翻转操作。
请你判断,能否通过旋转和翻转操作将第一个矩阵变为第二个矩阵。
旋转操作指将矩阵逆时针旋转 90,180,270度。翻转操作指将矩阵沿水平轴或垂直轴翻转。
输入格式
第一行包含整数 N。
接下来 N行,每行包含 N个字符,每个字符要么为 X
,要么为 O
,表示第一个矩阵。
接下来 N行,每行包含 N个字符,每个字符要么为 X
,要么为 O
,表示第二个矩阵。
输出格式
如果能够通过旋转和翻转操作将第一个矩阵变为第二个矩阵,则输出 Yes
,否则输出 No
。
数据范围
前 4个测试点满足 1≤N≤4。所有测试点满足 1≤N≤10。
输入样例1:
4
XOOO
XXOO
OOOO
XXXX
XOOO
XOOO
XOXO
XOXX
输出样例1:
Yes
输入样例2:
2
XX
OO
XO
OX
输出样例2:
No
八数码棋盘的方格数为 9,字符种数也为 9,则棋盘的状态数最多等于 9 个数的排列 A99=9!<109。而本题方格数最多 100,字符种数为 2,若字符 X 的个数为 m,则棋盘的状态数等于从 100 个方格选 m 个放 X,剩余方格放 O 的方案数 Cm100。当 m=10
时,有
C10100=100×99×98×97×⋯×9110×9×8×7×⋯×1>100×99×88×77×⋯×1110×9×8×7×⋯×1=10×119>109
因此,枚举棋盘的所有状态会超时。
分析:(本质一共8中情况)
#include <bits/stdc++.h> // 引入C++标准库,包括常用的头文件
using namespace std; // 使用标准命名空间
int n; // 定义一个整型变量n,表示矩阵的大小
vector<string> a, b; // 定义两个字符串向量a和b,用于存储输入的两个矩阵
// 定义一个函数flip,用于左右翻转矩阵
vector<string> flip(vector<string> a)
{
for (int i = 0; i < n; i++)
for (int j = 0, k = n - 1; j < k; j++, k--)
swap(a[i][j], a[i][k]);
return a;
}
// 定义一个函数rotate,用于逆时针旋转矩阵90度
vector<string> rotate(vector<string> a)
{
a = flip(a);
for (int i = 0; i < n; i++)
for (int j = 0; j < i; j++)
swap(a[i][j], a[j][i]);
return a;
}
// 定义一个函数check,用于检查两个矩阵是否可以通过旋转和翻转变得相同
bool check()
{
for (int i = 0; i < 4; i++)
{
a = rotate(a);
if (a == b) return true;
}
a = flip(a);
for (int i = 0; i < 4; i++)
{
a = rotate(a);
if (a == b) return true;
}
return false;
}
int main()
{
cin >> n; // 从标准输入读取矩阵的大小n
a = b = vector<string>(n); // 初始化两个矩阵a和b,大小为n
for (int i = 0; i < n; i++) cin >> a[i]; // 从标准输入读取矩阵a的元素
for (int i = 0; i < n; i++) cin >> b[i]; // 从标准输入读取矩阵b的元素
if (check()) cout << "Yes" << endl; // 如果两个矩阵可以通过旋转和翻转变得相同,输出"Yes"
else cout << "No" << endl; // 否则输出"No"
return 0; // 程序结束,返回0
}