Open In App

Maximum area of triangle having different vertex colors

Given a matrix of N rows and M columns, consists of three value {r, g, b}. The task is to find the area of the largest triangle that has one side parallel to y-axis i.e vertical and the color of all three vertices are different.
Examples: 
 

Input :  N = 4, M =5
  mat[][] =
  {
  r, r, r, r, r,
  r, r, r, r, g,
  r, r, r, r, r,
  b, b, b, b, b,
  }
Output : 10
The maximum area of triangle is 10.
Triangle coordinates are (0,0) containing r, (1,4) containing g, (3,0) containing b.

 

We know area of a triangle = 1/2 * base *height, so we need to maximize the base and height of the triangle. Since one side is parallel to the y-axis, we can consider that side as the base of the triangle.
To maximize base, we can find the first and last occurrence of {r, g, b} for each column. So we have two sets of 3 values for each column. For base in any column, one vertex is from the first set and the second vertex from the second set such that they have different values.
To maximize height, for any column as a base, the third vertex must be chosen such that the vertex should be farthest from the column, on the left or right side of the column having a value different from the other two vertices. 
Now for each column find the maximum area of the triangle.
Below is the implementation of this approach:
 




// C++ program to find maximum area of triangle
// having different vertex color in a matrix.
#include<bits/stdc++.h>
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);
        }
    }
 
    // finding 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 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)
             
    # finding 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




// C# program to find maximum area of triangle
// having different vertex color in a matrix.
using System;
 
class MainClass {
    const int R = 4;
    const int C = 5;
 
    // return the color value so that their corresponding
    // index can be access.
    static int mapcolor(char c)
    {
        if (c == 'r') {
            return 0;
        }
        else if (c == 'g') {
            return 1;
        }
        else if (c == 'b') {
            return 2;
        }
        else {
            return -1;
        }
    }
    // Returns the maximum area of triangle from all
    // the possible triangles
    static double findarea(char[, ] mat, int r, int c,
                           int[, ] top, int[, ] bottom,
                           int[] left, int[] right)
    {
        double ans = .0;
 
        // 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.MaxValue&&
                                      bottom[y, i]
                               != int.MinValue&& left[z]
                               != int.MaxValue) {
                        ans = Math.Max(
                            ans,
                            (1.0 / 2.0)
                                * (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.MaxValue&&
                                      bottom[y, i]
                               != int.MinValue&& right[z]
                               != int.MinValue) {
                        ans = Math.Max(
                            ans,
                            (1.0 / 2.0)
                                * (bottom[y, i] - top[x, i])
                                * (right[z] - i)+4);
                    }
                }
            }
        }
 
        return ans;
    }
    // Precompute the vertices of top, bottom, left
    // and right and then computing the maximum area.
    static double maxarea(char[, ] mat, int r, int c)
    {
        int[] left
            = { int.MaxValue, int.MaxValue, int.MaxValue };
        int[] right
            = { int.MinValue, int.MinValue, int.MinValue };
        int[, ] top = new int[3, C];
        int[, ] bottom = new int[3, C];
 
        // 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++) {
                int color = mapcolor(mat[i, j]);
 
                if (color != -1) {
                    left[color] = Math.Min(left[color], j);
                    right[color]
                        = Math.Max(right[color], j);
                }
            }
        }
        // finding 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++) {
                int color = mapcolor(mat[i, j]);
 
                if (color != -1) {
                    top[color, j]
                        = Math.Min(top[color, j], i);
                    bottom[color, j]
                        = Math.Max(bottom[color, j], i);
                }
            }
        }
 
        return findarea(mat, R, C, top, bottom, left,
                        right);
    }
 
    // Driven Program
    public static void Main(string[] args)
    {
        char[, ] mat = new char[, ] {
            { 'r', 'r', 'r', 'r', 'r' },
            { 'r', 'r', 'r', 'r', 'g' },
            { 'r', 'r', 'r', 'r', 'r' },
            { 'b', 'b', 'b', 'b', 'b' },
        };
 
        Console.WriteLine(maxarea(mat, R, C));
    }
}




// Javascript program to find maximum area of triangle
// having different vertex color in a matrix.
 
// return the color value so that their corresponding
// index can be accessed.
function mapcolor(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
function findarea(mat, r, c, top, bottom, left, right) {
  let ans = 10;
 
  // for each column
  for (let i = 0; i < c; i++) {
    // for each top vertex
    for (let x = 0; x < 3; x++) {
      // for each bottom vertex
      for (let y = 0; y < 3; y++) {
        // finding the third color of
        // vertex either on right or left.
        let z = 3 - x - y;
 
        // finding area of triangle on left side of column.
        if (x != y && top[x][i] != Number.MAX_SAFE_INTEGER &&
            bottom[y][i] != Number.MIN_SAFE_INTEGER &&
            left[z] != Number.MAX_SAFE_INTEGER) {
          ans = Math.max(ans, (1/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] != Number.MAX_SAFE_INTEGER &&
            bottom[y][i] != Number.MIN_SAFE_INTEGER &&
            right[z] != Number.MIN_SAFE_INTEGER) {
          ans = Math.max(ans, (1/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.
function maxarea(mat, r, c) {
  let left = [Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER];
  let right = [Number.MIN_SAFE_INTEGER, Number.MIN_SAFE_INTEGER, Number.MIN_SAFE_INTEGER];
  let top = Array.from({length: 3}, () => Array(c).fill(Number.MAX_SAFE_INTEGER));
  let bottom = Array.from({length: 3}, () => Array(c).fill(Number.MIN_SAFE_INTEGER));
 
  // finding the r, b, g cells for the left
  // and right vertices.
  for (let i = 0; i < r; i++) {
    for (let j = 0; j < c; j++) {
      let color = mapcolor(mat[i][j]);
      left[color] = Math.min(left[color], j);
      right[color] = Math.max(right[color], j);
    }
  }
 
  // finding set of {r, g, b} of top and
  // bottom for each column.
  for (let j = 0; j < c; j++) {
    for (let i = 0; i < r; i++) {
      let color = mapcolor(mat[i][j]);
      top[color][j] = Math.min(top[color][j], i);
      bottom[color][j] = Math.max(bottom[color][j], i);
    }
  }
 
  return findarea(mat, r, c, top, bottom, left, right);
}
 
// Driven Program
const R = 4;
const C = 5;
const mat = [
  ['r', 'r', 'r', 'r', 'r'],
  ['r', 'r', 'r', 'r', 'g'],
  ['r', 'r', 'r', 'r', 'r'],
  ['b', 'b', 'b', 'b', 'b'],
];
 
console.log(maxarea(mat, R, C));
// akashish__

Output: 

10

Time Complexity : O(R * C)
Auxiliary Space: O(R + C) 
Source: http://stackoverflow.com/questions/40078660/maximum-area-of-triangle-having-all-vertices-of-different-color

 


Article Tags :