zoukankan      html  css  js  c++  java
  • USACO Section 1.2 Transformations 解题报告

    题目

    题目描述

    一块 N x N正方形的黑白瓦片的图案要被转换成新的正方形图案。
    写一个程序来找出将原始图案按照以下列转换方法转换成新图案的最小方式:

    1. 转 90 度:图案按顺时针转 90 度.
    2. 转 180 度:图案按顺时针转 180 度.
    3. 转 270 度:图案按顺时针转 270 度.
    4. 翻转:图案在水平方向翻转(形成原图案的镜像).
    5. 组合:图案在水平方向翻转,然后按照1~3 之一转换.
    6. 不改变:原图案不改变.
    7. 无效转换:无法用以上方法得到新图案.

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

    数据范围

    1 <= N <= 10

    样例输入

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

    样例输出

    1

    解题思路

    这就是一个模拟,我们按照从小到达的序号依次枚举每一种操作,最后哪一种操作成功就输出哪种操作的序号。

    关键是要细心,模块化编程,仔细处理好各种操作即可。

    总结

    在开始写代码的时候我遇到了一个以前没有考虑过的情况,那就是如何用函数返回一个二维字符数组,在百度了很久之后我找到了一种办法,就是下面的第一份解题代码,利用返回一个指向指针数组的指针来实现,这种方法写起来比较麻烦一点,但是程序的可读性还是不错的。

    之后我看了官方标程,发现了一个更加巧妙的思路,那就是将图案保存在一个结构体中,我们每次操作直接返回一个结构体类型的变量,这样就避免了直接返回一个二维字符数组,并且这种写法可以使得程序更加的简短。这种思想我写在了下面的解题代码(Type 2)中。

    解题代码

    /*
    ID: yinzong2
    PROG: transform
    LANG: C++11
    */
    #define MARK
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    
    using namespace std;
    const int maxn = 15;
    
    int n;
    char plat[maxn][maxn], finalPlat[maxn][maxn];
    
    char **init() {
        char **a;
        a = new char*[n];
        for(int i = 0; i < n; i++) {
            a[i] = new char[n];
        }
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < n; j++) {
                a[i][j] = plat[i][j];
            }
        }
        return a;
    }
    
    char **rotate90(char **a, int row, int col) {
        char **p;
        p = new char*[row];
        for(int i = 0; i < row; i++) {
            p[i] = new char[col];
        }
        for(int i = 0; i < row; i++) {
            for(int j = 0; j < col; j++) {
                p[j][row-1-i] = a[i][j];
            }
            p[i][col] = '';
        }
        return p;
    }
    
    char **rotate180(char **a, int row, int col) {
        char **p;
        p = new char*[row];
        for(int i = 0; i < row; i++) {
            p[i] = new char[col];
        }
        p = rotate90(a, row, col);
        p = rotate90(p, row, col);
        return p;
    }
    
    char **rotate270(char **a, int row, int col) {
        char **p;
        p = new char*[row];
        for(int i = 0; i < row; i++) {
            p[i] = new char[col];
        }
        p = rotate180(a, row, col);
        p = rotate90(p, row, col);
        return p;
    }
    
    char **reflect(char **a, int row, int col) {
        char **p;
        p = new char*[row];
        for(int i = 0; i < row; i++) {
            p[i] = new char[col];
        }
        for(int i = 0; i < row; i++) {
            for(int j = 0; j < col; j++) {
                p[i][col-1-j] = a[i][j];
            }
            p[i][col] = '';
        }
        return p;
    }
    
    bool cmp(char **a) {
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < n; j++) {
                if(a[i][j] != finalPlat[i][j]) {
                    return false;
                }
            }
        }
        return true;
    }
    
    bool work(char **a, int row, int col) {
        char **p;
        p = new char*[row];
        for(int i = 0; i < row; i++) {
            p[i] = new char[col];
        }
        p = reflect(a, row, col);
        if(cmp( rotate90(p, n, n) )) return true;
        if(cmp( rotate180(p, n, n) )) return true;
        if(cmp( rotate270(p, n, n) )) return true;
        return false;
    }
    
    int main() {
    #ifdef MARK
        freopen("transform.in", "r", stdin);
        freopen("transform.out", "w", stdout);
    #endif // MARK
        while(~scanf("%d", &n)) {
            for(int i = 0; i < n; i++) {
                scanf("%s", plat[i]);
            }
            for(int i = 0; i < n; i++) {
                scanf("%s", finalPlat[i]);
            }
            char **a = init();
            int ans;
            if(cmp( rotate90(a, n, n) )) {
                ans = 1;
            } else if(cmp( rotate180(a, n, n) )) {
                ans = 2;
            } else if(cmp( rotate270(a, n, n) )) {
                ans = 3;
            } else if(cmp( reflect(a, n, n) )) {
                ans = 4;
            } else if(work(a, n, n)) {
                ans = 5;
            } else if(cmp(a)) {
                ans = 6;
            } else {
                ans = 7;
            }
            printf("%d
    ", ans);
            delete(a);
        }
        return 0;
    }
    

    解题代码(Type 2)

    /*
    ID: yinzong2
    PROG: transform
    LANG: C++11
    */
    #define MARK
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    
    using namespace std;
    const int maxn = 15;
    
    int n;
    
    struct Plat {
        char p[maxn][maxn];
    };
    
    Plat plat, finalPlat;
    
    Plat rotate90(Plat a) {
        Plat np;
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < n; j++) {
                np.p[j][n-1-i] = a.p[i][j];
            }
            np.p[i][n] = '';
        }
        return np;
    }
    
    Plat reflect(Plat a) {
        Plat np;
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < n; j++) {
                np.p[i][n-1-j] = a.p[i][j];
            }
            np.p[i][n] = '';
        }
        return np;
    }
    
    bool cmp(Plat a, Plat b) {
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < n; j++) {
                if(a.p[i][j] != b.p[i][j]) {
                    return false;
                }
            }
        }
        return true;
    }
    
    int main() {
    #ifdef MARK
        freopen("transform.in", "r", stdin);
        freopen("transform.out", "w", stdout);
    #endif // MARK
        while(~scanf("%d", &n)) {
            for(int i = 0; i < n; i++) {
                scanf("%s", plat.p[i]);
            }
            for(int i = 0; i < n; i++) {
                scanf("%s", finalPlat.p[i]);
            }
            int ans;
            if(cmp(finalPlat, rotate90(plat))) {
                ans = 1;
            } else if(cmp(finalPlat, rotate90(rotate90(plat)))) {
                ans = 2;
            } else if(cmp(finalPlat, rotate90(rotate90(rotate90(plat))))) {
                ans = 3;
            } else if(cmp(finalPlat, reflect(plat))) {
                ans = 4;
            } else if(cmp(finalPlat, rotate90(reflect(plat)))
                    ||cmp(finalPlat, rotate90(rotate90(reflect(plat))))
                    ||cmp(finalPlat, rotate90(rotate90(rotate90(plat))))) {
                ans = 5;
            } else if(cmp(finalPlat, plat)) {
                ans = 6;
            } else {
                ans = 7;
            }
            printf("%d
    ", ans);
        }
        return 0;
    }
    
  • 相关阅读:
    思考题
    对敏捷开发的见解
    Code Review(自评)
    求数组最大子数组和
    [ASP.NET]在虚拟目录中禁止web.config继承IIS根目录的web.config的配置
    客户的真实需求
    利用using和try/finally語句來清理資源.
    《代码整洁之道》简单总结
    ASP.NET页面级别的事
    根据DIV移动生成图片
  • 原文地址:https://www.cnblogs.com/yinzm/p/5807396.html
Copyright © 2011-2022 走看看