一道关于三角型的题

本题摘自 www.topcoder.com

题目如下:你有一个很多方形格子所组成的矩阵组,一些小方格是黑色的,一些是白色的,而一些是三角型的格子的,三角的格子可以任意90度的旋转也可以打开变成黑色的格子,但任何小格被放置好就不可以再移动

你的任务是找出在这个矩阵组中有多少个潜在的独立的三角型

我们会给你一组数组表示这个矩阵,其中'#' 代表黑色的方块,'/'代码三角型,'.'代表白色的方块

如图 一道关于三角型的题

将会被表示为{"#//#./#/#",

                         "####.#/##",

                         "...../#.#",

                         ".....####"}; 这样的一个矩阵,下面的图列将会分析出这个图里潜在的三角型数
一道关于三角型的题




如图所见,当我们获得这样的一个参数时,有且只有5个独立的三角型图案

以下给出一些类似的参数输入及输出

Constraints 
-  grid will contain between 1 and 50 elements, inclusive. 
-  Each element of grid will contain between 1 and 50 characters, inclusive. 
-  Each element of grid will contain the same number of characters. 
-  Each character in grid will be '.', '#' or '/'. 
Examples 
0)  
      {"//"}

Returns: 10



1)  
      {"#//#./#/#",
"####.#/##",
"...../#.#",
".....####"}

Returns: 5
This is the example from the statement. 


2)  
      {".#.",
"#/#",
".#."}

Returns: 0



3)  
      {".../...",
"..///./",
".//#/./"}

Returns: 46



如何来判断一个三角型是否是一个独立的三角型?

首先,一个独立的三角型,必须有2边不是连接着黑色的小方块的,也就是说直角边的2边必须要是空白的小方块,三角型,或者是墙。

可能你会马上这样考虑,那么我遍历这个矩阵,找到所有的三角型,毕竟只有找到三角型才能判断它的2边。但是这样做实际会让第二个问题(组合3角型)变得很麻烦,一个大三角型完全可以包含多个三角型,而且2个大直角三角型,可以组合成为一个等腰三角型。这些都让这个题目的难度增加了很多



请看这张图,恩,很丑: 一道关于三角型的题


从左边的图像可以看到1,1这个位置是一个黑色的方块,而1,2这个位置是一个三角型,他们分别属于2个直角三角型,但和在一起变成了一个大三角型,而0,1 和0,2 只有在倒立的情况下才能算一个独立的三角型,如现在所示他们只能贴着1,1这个黑色方块,所以它们无法算做一个三角型

右边的图有一个大三角型但如果你像现在这样放置那2个小的三角型,这这2个图案都不独立的三角型了,如果把那2个小三角型的方向变成 》 大三角型仍然是|— 则他们2 都是三角型,为2个不同的三角型



想了一天大概找到了一些判断的规则和解题的思路,PS:如果你有其他的做法不妨一起讨论下



1 三角型是可以旋转的,这里我们不旋转三角型,而是旋转整个矩阵,然后根据条件2,4找寻符合条件的项,一共旋转3次

2 如何判断一个三角型是一个小三角型,不考虑组合时,很显然,当它的2边为空,墙,三角型时条件成立。所以我们每次都查找三角型格的右侧和下侧,符合要求则成立,如果右侧为三角型还需在跳至规则3判断

3 两个小三角型紧贴在一起的时候有可能合并成为一个占2格的稍大一些的三角型,根据条件1,如果该小三角型的右侧为三角型,并且其下侧的2个格子任何一个都不为黑色方块 ,则成立。之后通过条件1旋转,检查另一个方向是否出现

4 直角大三角型,开始方块不能为空白方块,然后开始检查它所有的斜对角线,如果有空白方块则退出,如果检查到斜对角线全部为三角型方块,并且其不含空白方块,则再检查其2条直角边,跳至规则5

5必须判断大直角三角型的2个直角边,是否有黑色方块紧贴,如果有则该图形不是直角三角型,并跳至规则6继续判断

6 两个大直角三角型组成的三角型,如果一个大直角三角型一边含有黑色方块,那他很可能紧贴着另一个大直角三角型那么我们还需反向判断,看是否存在这样的一个映射三角型,判断参考规则4,5

解决问题的是人,不是程序



   代码如下:

public class RotatingTriangles {    
   
    int n = 0;    
    int m = 0;    
    String[] t_grid;    
        
    public static void main(String[] args){    
        String[] test1={"//"};    
        String[] test2={"#//#./#/#","####.#/##","...../#.#",".....####"};    
        String[] test3={".#.", "#/#",".#."};    
        String[] test4={".../...","..///./",".//#/./"};    
        //should output 10    
        new RotatingTriangles().count(test1);    
        //should output 5    
        new RotatingTriangles().count(test2);    
        // 0     
        new RotatingTriangles().count(test3);    
        //46    
        new RotatingTriangles().count(test4);    
    }    
        
    public int count(String[] grid) {    
        t_grid = grid;    
        int res = 0;    
        for (int i = 0; i < 4; i++) {    
            res += countTriangle(t_grid);    
            t_grid = rotate(t_grid);    
        }    
        return res;    
    }    
   
    public int countTriangle(String[] grid) {    
        t_grid = grid;    
        n = grid.length;    
        m = grid[0].length();    
        int res = 0;    
   
        for (int i = 0; i < n; i++) {    
            for (int j = 0; j < m; j++) {    
                char currentChar = getCV(i, j);    
                if (currentChar == '/') {    
                    if (j + 1 < m) {    
                        if (i + 1 < n) {    
                            if (getCV(i, j + 1) == '.'&& getCV(i + 1, j) != '#'){ res++;}    
                            if (getCV(i, j + 1) == '/'&& getCV(i + 1, j) != '#'){    
                                res++;    
                                if(getCV(i + 1, j + 1) != '#'){ res++; }    
                            }    
                        } else {    
                            if (getCV(i, j + 1) == '.'){ res++;}    
                            if (getCV(i, j + 1) == '/'){ res+=2;}    
                        }    
                    } else {    
                        if (i + 1 < n) {    
                            if(getCV(i + 1, j) != '#'){res++;}    
                        } else {    
                            res++;    
                        }    
                    }    
                }    
                    
                // judge the big T    
                int a = i + 1, b = j + 1;    
                boolean whileflag = true;    
                    
                while (a < n && b < m && whileflag && currentChar != '.') {    
                        
                    char c = checkDiagonal(a,b,i,j,false);    
                        
                    if(c=='.') break;    
                        
                    if (whileflag && c == '/') {    
                        if (i - 1 >=0) {    
                            whileflag = checkHorizontalLine(i-1,j,b);    
                            if (whileflag) {    
                                if(j-1>0){    
                                    for (int h = i; h <= a; h++){    
                                        if (getCV(h, j - 1) == '#') {    
                                            whileflag = false;    
                                            break;    
                                        }    
                                    }    
                                }    
                            }    
                            if(b-j<=j){    
                                if('/'==checkDiagonal(a,b,i,j,true)){    
                                    if(checkHorizontalLine(2*j-b,j,j-1))    
                                        res++;    
                                }    
                            }    
                        }    
                        if (j - 1 >= 0&&whileflag) {    
                            for (int h = i; h <= a; h++){    
                                if (getCV(h, j - 1) == '#') {    
                                    whileflag = false;    
                                    break;    
                                }    
                            }       
                        }    
                        if (whileflag) { res++; a++; b++;}    
                    }    
                        
                    if (whileflag && c == '#') {a++; b++;}    
                }    
            }    
        }    
        return res;    
    }      
   
    public char getCV(int n, int m) {    
        return t_grid[n].charAt(m);    
    }    
        
    public boolean checkHorizontalLine(int hight,int start,int end){    
        boolean flag=true;    
        for (int w = start; w <= end; w++){    
            if (getCV(hight, w) == '#') {    
                flag = false;    
                break;    
            }      
        }    
        return flag;    
    }    
        
    public char checkDiagonal(int a,int b,int i,int j,boolean inverse){    
        char c = '0';    
        if(inverse){    
            for (int x = a-1, y = j; x <= j && y >=a; x++, y--) {    
                if (c == '0') {    
                    c = getCV(x, y);    
                } else {    
                    if (getCV(x, y) == '.') {    
                        c='.';    
                        break;    
                    }     
                    c = getCV(x, y)== c ? c : '#';    
                }    
            }    
        }else{    
            for (int x = a, y = j; x >= i && y <= b; x--, y++) {    
                if (c == '0') {    
                    c = getCV(x, y);    
                } else {    
                    if (getCV(x, y) == '.') {    
                        c='.';    
                        break;    
                    }     
                    c = getCV(x, y)== c ? c : '#';    
                }    
            }    
        }    
        return c;    
    }    
        
    public String[] rotate(String[] grid) {    
        int h = grid.length;    
        int w = grid[0].length();    
        String[] temp = new String[w];    
   
        for (int i = 0; i < w; i++) {    
            String s = "";    
            for (int j = 0; j < h; j++)    
                s += grid[j].charAt(i) + "";    
            temp[w - i - 1] = s;    
        }    
        return temp;    
    }    
}  
 

你可能感兴趣的:(C++,c,C#,J#)