前两天打了CCPC网络赛(让打老实了),现在认识到了刷题的重要性,于是我开创了这么个栏目,我们一起刷一下题。
还是在ACwing网站上刷题 旋转和翻转
首先,申一下题目,输入一个数字 n ,来表示矩阵的行和列,之后输入两个矩阵,判断一下两个矩阵相互能否通过旋转和翻转来相互转换。如果能,输出Yes,否则输出No。
如果没有见过翻转和旋转的题目,可能会发懵,面对一个矩阵,它可能进行多次运动得到另一个矩阵,我们不能通过运动的层次去分析这道题,这样分析有无限种可能,我们要从状态来分析,比如一个矩阵
它通过旋转可以得到四种状态,通过翻转加旋转又可以得到四种状态,所以总共就是八种状态,(这里我插进来图片不太好看,大家可以自己手写一下,写一下就很容易就明白了),在题中,如果我们可以一一找出输入的第一个矩阵的八种状态,并对于第二个矩阵做对比,如果有和第二个矩阵相同的,就输出Yes,否则输出No。
代码如下:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
int n;
vector<string> a,b;
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;
}
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;
}
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;
a = b = vector<string>(n);
for(int i = 0; i < n ; i ++ ) cin >> a[i];
for(int i = 0; i < n ; i ++ ) cin >> b[i];
if(check()) cout << "Yes" <<endl;
else cout << "No" << endl;
return 0;
}
在这个代码中,最重要的就是翻转 flip 和旋转 rotate 这两个操作,flip 理解起来比较简单,就是左右的字符对换了一下位置,比如abcd1234efgh这个矩阵,就变成了下面这样,以中间为对称轴,来对换。
至于旋转,我们是先进行左右翻转操作,再进行以对角线为对称轴进行翻转,以达到旋转90度的目的,再举一个例子
实在不行的话,可以随便找一本书来手动翻转试一下,很有意思的现象。
另外还要注意,这里我们是用vector字符数组来存储的,希望大家习惯用这种方式,好处在于,可以比较方便地进行输入,以及支持二位数组,支持swap交换函数。
好,下课