zoukankan      html  css  js  c++  java
  • UVALive.2995 Image Is Everything (思维题 三维坐标转换)

    UVALive.2995 Image Is Everything (思维题 三维坐标转换)

    题意分析

    这题实在是没思路,就照着打了一遍,把不理解的地方,写了注释。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define REP(i,n)  for(int i = 0; i<(n) ;++i)// 宏定义一个for循环
    #define nmax 10
    using namespace std;
    char view[6][nmax][nmax];
    char pos[nmax][nmax][nmax];
    int n;
    char read()
    {
        char ch;
        for(;;){
            ch = getchar();
            if((ch>='A' && ch<= 'Z') || ch == '.')
                return ch;
        }
    }
    void get(int k, int i, int j, int len, int &x, int &y, int &z)
    {
        if(k == 0) {x = len ; y = j; z = i;}
        //1. k = 0 表示的是前视图,如果发现前视图有一个.的话那么就要把所有后面的
        //  都置为.来表示没有方格。 但是这里有一个xy的坐标变换,不明白为什么。 还要思考。
        if(k == 1) {x = n-1-j ; y = len ;z = i;}
        //2. k = 1 表示的是左视图,如果发现左视图有一个.的话,那么就要把从左向右的对应位置的
        //   方格都处理为.。注意这里的坐标变换。由于是从左看的,正视图的最后一层,对应的应该是
        //   左视图的第一列,故横坐标x对应的变换应该是x=n-1-j(还需要-1是因为数组从0开始),纵坐标的对应变换应该是
        //   y = len,即实参中的p,p的实际含义是从这个方格开始向后处理n次,转换成正视图中为对应的y。不难发现z对应的是i。
        if(k == 2) {x = n -1 - len; y= n -1- j; z= i;}
        //3. k = 2 表示的是后视图(真的好别扭),如果发现后视图中有一个.的话,就要从后往前将对应位置的方格
        //   处理为.。 坐标变换,x表示层数,不难推出是 n-1-len(即传入的参数p),y应该是n-1-j(如果画图的话,会发现其实
        //   坐标轴都相反,故xy形式类似),也不难看出z相同。
        if(k == 3) {x = j; y = n -1 - len; z = i;}
        //4. k = 3 表示的是右视图(感觉和左视图类似?)。先看z,不难看出z和i相同。y和en坐标相反,x和j坐标相同。其实会发现,
        //   画个图,然后相反就按照相反的公式套一下,相同就是相等。
        if(k == 4) {x = n-1-i ; y = j; z = len;}
        //5. k = 4 表示的是顶视图,先画个图,然后救护发现,y和j相同,x和i相反,z和len相同。
        if(k == 5) {x = i; y = j; z = n-1- len;}
        //6. k = 5 表示的是底视图,按照相同的方法,先画图,然后找坐标变换。注意这个底视图是从正视图的那个最左下角的那个块为
        //   为底视图的左上角的块的,一开始画错了,找不到正确的变换方程。只有z和len相反,x和i相同,y和j相同。
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        while(scanf("%d",&n) && n){
             //由于数据是按照行给出的额,因此必须按照行读入。故在此处必须要按照一定规则处理。
             REP(i,n) REP(k,6) REP(j,n) view[k][i][j] = read();
             // 初始化pos数组
             REP(i,n) REP(j,n) REP(k,n) pos[i][j][k] = '#';
    
             //由于已经读入了数据,故可以按照视图,从i到j的方向处理view数组了。
             //若视图中的某一个方块为.,表示其方向上的所有方块都没有。
             REP(k,6) REP(i,n) REP(j,n) if(view[k][i][j] == '.'){
                REP(p,n){
                    int x,y,z;
                    //我的妈呀传这么多参数干啥呀
                    get(k,i,j,p,x,y,z);
                    //看完get函数就会发现其实是对各个视图的.完成了一个坐标变换,处理掉一条线上的.。
                    //注意这里对实际的的pos数组,即实际保存方块的数组。
                    pos[x][y][z] = '.';
                }
             }
             for(;;){
                bool done = true;
                // 开始处理不是.的方块, 如果一视图中某位置不为.那么->
                REP(k,6) REP(i,n) REP(j,n) if(view[k][i][j] != '.'){
                    //接着对n层进行处理
                    REP(p,n){
                        int x,y,z;
                        //和刚才一样进行一个坐标变换,找到方格对应的x,y,z坐标
                        get(k,i,j,p,x,y,z);
                        //判断一下 如果实际保存方块的数组中对应位置也是.的话, 继续看下一层。
                        if(pos[x][y][z] == '.') continue;
                        //若找到一个方块的颜色还是未确定的话,那么是的这个块的颜色与视图颜色相同,且结束对这一列块的查找。
                        //原因很简单,从一面看,最多只能看到最外面的那个块的颜色,他后面的也看不到呀
                        if(pos[x][y][z] == '#') {
                            pos[x][y][z] = view[k][i][j];
                            break;
                        }
                        //如果这个块已经被赋上颜色了(即不属于上面的2种情况),那么就检查一下,当前块的颜色是否和某视图的颜色相同
                        //如果相同的话,本列查找结束(结束原因和上面相同),否则的话->
                        if(pos[x][y][z] == view[k][i][j]) break;
                        //(接上一个否则),这个块的颜色和视图的颜色对不上号,说明矛盾,即这个块不应该存在,置为.。同时说明,当前
                        //仍然有不匹配的地方,还需要进行重新的检查.done置为false.
                        pos[x][y][z] = '.';
                        done = false;
                    }
                }
                if(done) break;
             }
             //最后遍历方块一遍,输出个数。
             int ans = 0;
             REP(i,n) REP(j,n) REP(k,n)
                if(pos[i][j][k] != '.') ans++;
             printf("Maximum weight: %d gram(s)
    ",ans);
        }
        return 0;
    }
    
  • 相关阅读:
    zzulioj1908: 小火山的围棋梦想
    zzulioj1913: 小火山的计算能力
    zullioj1905: 小火山的跳子游戏
    HDU 1025:Constructing Roads In JGShining's Kingdom
    HDU 1257:最少拦截系统
    HDU1051:Wooden Sticks
    HDU1950:Bridging signals
    HDU1087:Super Jumping! Jumping! Jumping!
    HDU5256: 序列变换
    3.SpringBoot配置文件以及自动配置原理
  • 原文地址:https://www.cnblogs.com/pengwill/p/7367129.html
Copyright © 2011-2022 走看看