P1205 [USACO1.2] 方块转换 Transformations

题目描述

一块 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 13 之间的一种再次转换。

  • 不改变:原图案不改变。

  • 无效转换:无法用以上方法得到新图案。

如果有多种可用的转换方法,请选择序号最小的那个。

只使用上述 7 7 7 个中的一个步骤来完成这次转换。

输入格式

第一行一个正整数 n n n

然后 n n n 行,每行 n n n 个字符,全部为 @-,表示初始的正方形。

接下来 n n n 行,每行 n n n 个字符,全部为 @-,表示最终的正方形。

输出格式

单独的一行包括 1 ∼ 7 1 \sim 7 17 之间的一个数字(在上文已描述)表明需要将转换前的正方形变为转换后的正方形的转换方法。

样例 #1

样例输入 #1

3
@-@
---
@@-
@-@
@--
--@

样例输出 #1

1

提示

【数据范围】
对于 100 % 100\% 100% 的数据, 1 ≤ n ≤ 10 1\le n \le 10 1n10

1.题目分析

主要是考查二维数组的使用,除此之外就是空间想象能力。
大概题意就是:输入一个n表示矩阵的阶数,输入两个字符N阶的字符矩阵,
第一个矩阵表示初始图案,第二个表示最终图案。
题目一共给出了七种方案和结果,根据初始矩阵最后的变换结果输出是方案几。

值得一提的是,我这里使用的是C++的输入,刚开始用的C写的,需要使用getchar()函数消除scanf()函数的换行符,但是由于做题网站的编译系统是部署在Linux上的,依旧报错,之所以这里使用了C++的输入方式,是因为他和Java一样是跨平台的。

2.题目思路

定义两个函数:
比较函数:输入两个数组,比较是否相同,用于判别最终结果。
打印函数:用于查看临时数组里的图案变换情况。
将初始图案和目标图案分别存入字符二维数组arr1和arr2,定义一个临时二维数组,用于和目标数组比较。接下来,将初始图案变换之后赋值给临时数组,顺序判断:

  • 转90
  • 转180
  • 转270
  • 反射
  • 组合
  • 不改变:原图案不改变
  • 无效转换

(这些变化就是一些行和列的交换,也没什么好讲的)

对应这七种变化,如果满足(临时数组和目标数组通过比较函数判别相同时)则打印相应方案的序号。当然,为了方便做题,使用打印函数观察变化结果也是必不可少的。

3.代码演示

#include 
#include 

using namespace std;

//比较两个数组是否一致
int compareTo(char arr1[10][10], char arr2[10][10], int n) {
    int flag = 1;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            if (arr1[i][j] != arr2[i][j]) {
                flag = 0;
            }
        }
    }
    return flag;
}

//用于查看图案变换情况
void print(char arr[10][10], int n) {
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            printf("%c", arr[i][j]);
        }
        printf("\n");
    }
}

int main() {
    int n;
    scanf("%d", &n);
    char arr1[10][10];
    char arr2[10][10];
    char temp[10][10];
    char c;
    //初始图案插入
    for (int i = 0; i < n; ++i) {
//        getchar();
        for (int j = 0; j < n; ++j) {
//            scanf("%c", &c);
            cin >> c;
            arr1[i][j] = c;
        }
    }
    //最后结果的图案
    for (int i = 0; i < n; ++i) {
        //消除换行符
//        getchar();
        for (int j = 0; j < n; ++j) {
//            scanf("%c", &c);
            cin >> c;
            arr2[i][j] = c;
        }
    }
    //转90
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            temp[j][n - 1 - i] = arr1[i][j];
        }
    }
    if (compareTo(temp, arr2, n) == 1) {
        printf("1\n");
        return 0;
    }
    //转180
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            temp[n - 1 - i][n - 1 - j] = arr1[i][j];
        }
    }
    if (compareTo(temp, arr2, n) == 1) {
        printf("2\n");
        return 0;
    }
    //转270
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            temp[n - 1 - j][i] = arr1[i][j];
        }
    }
    if (compareTo(temp, arr2, n) == 1) {
        printf("3\n");
        return 0;
    }
    //反射
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            temp[i][n - 1 - j] = arr1[i][j];
        }
    }
    if (compareTo(temp, arr2, n) == 1) {
        printf("4\n");
        return 0;
    }
    //组合
    char ch[10][10];//用于存储组合之后的图案
    //1∼3 之间的一种再次转换。
    //组合转90
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            ch[j][n - 1 - i] = temp[i][j];
        }
    }
    if (compareTo(ch, arr2, n) == 1) {
        printf("5\n");
        return 0;
    }
    //组合转180
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            ch[n - 1 - i][n - 1 - j] = temp[i][j];
        }
    }
    if (compareTo(ch, arr2, n) == 1) {
        printf("5\n");
        return 0;
    }
    //组合转270
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            ch[n - 1 - j][i] = temp[i][j];
        }
    }
    if (compareTo(ch, arr2, n) == 1) {
        printf("5\n");
        return 0;
    }
    //不改变:原图案不改变
    if (compareTo(arr1, arr2, n) == 1) {
        printf("6\n");
        return 0;
    }
    //无效转换
    if (compareTo(temp, arr2, n) == 0 || compareTo(ch, arr2, n) == 0) {
        printf("7\n");
    }
    return 0;
}

你可能感兴趣的:(刷题go,go,go,算法,开发语言)