USACO转换(矩阵变换,模拟)

我们现在要将一个 N×N大小的由黑白瓷砖构成的正方形图案转换为一个新的正方形图案。

共有 7 种转换方式如下:

90 度旋转:将图案顺时针旋转 90 度。
180 度旋转:将图案顺时针旋转 180 度。
270 度旋转:将图案顺时针旋转 270 度。
镜像:沿着图片的中间垂直线翻转图片,使其变为自身的镜像。
组合:先进行镜像转换,再按照 13 中的一种方式进行转换。
不改变:保持原图案,不做任何改变。
无效转换:上述任何一种方式都无法得到新图案。

如果只允许使用上述方式中的一种进行图形转换,能否将原图案转换为新图案?

请你求出用哪种转换方式,可以得到新图案,输出这一方式的序号。

如果有多种方式可以满足条件,则输出序号较小的方式的序号。

当然,如果无法完成转换,只能输出方式 7 无效转换。

输入格式
第一行一个整数 N,表示正方形图案的大小。

接下来 N 行,每行包含 N 个字符(‘-’或‘@’),表示初始的正方形图案。

再接下来 N 行,每行包含 N 个字符(‘-’或‘@’),表示希望得到的新正方形图案。

输出格式
输出一个 1∼7 之间的整数,表示将原图案转换为新图案所使用的具体转换方式的序号。

数据范围
1≤N≤10
输入样例:
3
@-@
---
@@-
@-@
@--
--@
输出样例:
1
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>

using namespace std;

typedef vector<string> VS;

int n;

void mirror(VS& s)
{
    
    
    for (int i = 0; i < n; i ++ )
        for (int j = 0, k = n - 1; j < k; j ++ , k -- )
            swap(s[i][j], s[i][k]);
}

void rotate(VS& s)//90度旋转可以先主对角线交换,然后镜像操作
{
    
    
    for (int i = 0; i < n; i ++ )
        for (int j = 0; j < i; j ++ )
            swap(s[i][j], s[j][i]);
    mirror(s);
}

int check(VS& a, VS& b)
{
    
    
    VS c = a;
    for (int i = 1; i <= 3; i ++ )
    {
    
    
        rotate(c);
        if (c == b) return i;
    }
    c = a;
    mirror(c);
    if (c == b) return 4;
    for (int i = 1; i <= 3; i ++ )
    {
    
    
        rotate(c);
        if (c == b) return 5;
    }
    if (a == b) return 6;
    return 7;
}

int main()
{
    
    
    VS a, b;
    string line;

    cin >> n;
    for (int i = 0; i < n; i ++ ) cin >> line, a.push_back(line);
    for (int i = 0; i < n; i ++ ) cin >> line, b.push_back(line);
    printf("%d\n", check(a, b));

    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43738331/article/details/112760091
今日推荐