📜  具有不同顶点颜色的三角形的最大面积

📅  最后修改于: 2021-04-24 14:44:22             🧑  作者: Mango

给定一个NM列的矩阵,它由三个值{r,g,b}组成。任务是找到最大一侧与y轴平行(即垂直)的最大三角形的面积,并且所有三个顶点的颜色都不同。

例子:

输入: N = 4,M = 5 mat [] [] = {r,r,r,r,r,r,r,r,g,r,r,r,r,r,b,b, b,b,b,}输出: 10三角形的最大面积为10。三角形坐标为(0,0)包含r,(1,4)包含g,(3,0)包含b。

我们知道三角形的面积= 1/2 *基数*高,因此我们需要最大化三角形的基数和高度。由于一侧平行于y轴,因此我们可以将该侧视为三角形的底。

为了最大化基数,我们可以找到每一列的{r,g,b}的第一个和最后一个出现。因此,每列有两组3个值。对于任何列中的基,一个顶点来自第一组,第二顶点来自第二组,以使它们具有不同的值。

为了使高度最大化,对于任何以列为基础的列,必须选择第三个顶点,以使该顶点离列最远,并且在列的左侧或右侧具有与其他两个顶点不同的值。
现在,对于每一列,找到三角形的最大面积。

以下是此方法的实现:

C++
// C++ program to find maximum area of triangle
// having different vertex color in a matrix.
#include
using namespace std;
#define R 4
#define C 5
  
// return the color value so that their corresponding
// index can be access.
int mapcolor(char c)
{
    if (c == 'r')
        return 0;
    else if (c == 'g')
        return 1;
    else if (c == 'b')
        return 2;
}
  
// Returns the maximum area of triangle from all
// the possible triangles
double findarea(char mat[R][C], int r, int c,
                int top[3][C], int bottom[3][C],
                int left[3], int right[3])
{
    double ans = (double)1;
  
    // for each column
    for (int i = 0; i < c; i++)
  
        // for each top vertex
        for (int x = 0; x < 3; x++)
  
            // for each bottom vertex
            for (int y = 0; y < 3; y++)
            {
                // finding the third color of
                // vertex either on right or left.
                int z = 3 - x - y;
  
                // finding area of triangle on left side of column.
                if (x != y && top[x][i] != INT_MAX &&
                    bottom[y][i] != INT_MIN && left[z] != INT_MAX)
                {
                    ans = max(ans, ((double)1/(double)2) *
                                   (bottom[y][i] - top[x][i]) *
                                    (i - left[z]));
                }
  
                // finding area of triangle on right side of column.
                if (x != y && top[x][i] != INT_MAX &&
                              bottom[y][i] != INT_MIN &&
                              right[z] != INT_MIN)
                {
                    ans = max(ans, ((double)1/(double)2) *
                                    (bottom[y][i] - top[x][i]) *
                                    (right[z] - i));
                }
            }
  
    return ans;
}
  
// Precompute the vertices of top, bottom, left
// and right and then computing the maximum area.
double maxarea(char mat[R][C], int r, int c)
{
    int left[3], right[3];
    int top[3][C], bottom[3][C];
    memset(left, INT_MAX, sizeof left);
    memset(right, INT_MIN, sizeof right);
    memset(top, INT_MAX, sizeof top);
    memset(bottom, INT_MIN, sizeof bottom);
  
    // finding the r, b, g cells for the left
    // and right vertices.
    for (int i = 0; i < r; i++)
    {
        for (int j = 0; j < c; j++)
        {
            left[mapcolor(mat[i][j])] =
                  min(left[mapcolor(mat[i][j])], j);
            right[mapcolor(mat[i][j])] =
                  max(left[mapcolor(mat[i][j])], j);
        }
    }
  
    // finsing set of {r, g, b} of top and
    // bottom for each column.
    for (int j = 0; j < c; j++)
    {
        for( int i = 0; i < r; i++)
        {
            top[mapcolor(mat[i][j])][j] =
                 min(top[mapcolor(mat[i][j])][j], i);
            bottom[mapcolor(mat[i][j])][j] =
                 max(bottom[mapcolor(mat[i][j])][j], i);
        }
    }
  
    return findarea(mat, R, C, top, bottom, left, right);
}
  
// Driven Program
int main()
{
    char mat[R][C] =
    {
        'r', 'r', 'r', 'r', 'r',
        'r', 'r', 'r', 'r', 'g',
        'r', 'r', 'r', 'r', 'r',
        'b', 'b', 'b', 'b', 'b',
    };
  
    cout << maxarea(mat, R, C) << endl;
    return 0;
}


Python3
# Python3 program to find the maximum 
# area of triangle having different 
# vertex color in a matrix. 
  
# Return the color value so that their 
# corresponding index can be access. 
def mapcolor(c): 
  
    if c == 'r': 
        return 0
    elif c == 'g':
        return 1
    elif c == 'b':
        return 2
  
# Returns the maximum area of triangle 
# from all the possible triangles 
def findarea(mat, r, c, top, 
             bottom, left, right): 
  
    ans = 1
  
    # for each column 
    for i in range(0, c): 
  
        # for each top vertex 
        for x in range(0, 3): 
  
            # for each bottom vertex 
            for y in range(0, 3): 
                          
                # finding the third color of 
                # vertex either on right or left. 
                z = 3 - x - y 
  
                # finding area of triangle on 
                # left side of column. 
                if (x != y and top[x][i] != INT_MAX and
                    bottom[y][i] != INT_MIN and 
                    left[z] != INT_MAX): 
                                      
                    ans = max(ans, 0.5 * (bottom[y][i] - 
                              top[x][i]) * (i - left[z]))
                                  
                # finding area of triangle on right side of column. 
                if (x != y and top[x][i] != INT_MAX and
                    bottom[y][i] != INT_MIN and
                    right[z] != INT_MIN):
                                  
                    ans = max(ans, 0.5 * (bottom[y][i] - 
                              top[x][i]) * (right[z] - i))
                  
    return ans 
  
# Precompute the vertices of top, bottom, left 
# and right and then computing the maximum area. 
def maxarea(mat, r, c): 
  
    left = [-1] * 3
    right = [0] * 3
    top = [[-1 for i in range(C)] 
               for j in range(3)]
    bottom = [[0 for i in range(C)] 
                 for j in range(3)]
          
    # finding the r, b, g cells for 
    # the left and right vertices. 
    for i in range(0, r): 
      
        for j in range(0, c): 
                  
            left[mapcolor(mat[i][j])] = \
                min(left[mapcolor(mat[i][j])], j)
                          
            right[mapcolor(mat[i][j])] = \
                max(left[mapcolor(mat[i][j])], j) 
              
    # finsing set of r, g, b of top 
    # and bottom for each column. 
    for j in range(0, c): 
          
        for i in range(0, r): 
                  
            top[mapcolor(mat[i][j])][j] = \
                min(top[mapcolor(mat[i][j])][j], i)
                              
            bottom[mapcolor(mat[i][j])][j] = \
                max(bottom[mapcolor(mat[i][j])][j], i)
                      
    return int(findarea(mat, R, C, top, 
                        bottom, left, right)) 
  
# Driver Code
if __name__ == "__main__":
          
    R, C = 4, 5
    mat = [['r', 'r', 'r', 'r', 'r'], 
           ['r', 'r', 'r', 'r', 'g'], 
           ['r', 'r', 'r', 'r', 'r'], 
           ['b', 'b', 'b', 'b', 'b']] 
          
    INT_MAX, INT_MIN = float('inf'), float('-inf')
    print(maxarea(mat, R, C))
  
# This code is contributed by Rituraj Jain


输出:

10

时间复杂度: O(M * N)。

资料来源: http://stackoverflow.com/questions/40078660/maximum-area-of-triangle-having-all-vertices-of-different-color