Open In App

Rectangular Plane Division – Min and Max Coordinates

Last Updated : 08 Oct, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

There is a rectangular plane with dimensions W * H which occupies rectangular area {(x,y): 0 ≤ x ≤ W, 0 ≤ y ≤H. There are N coordinates represented by array cor[][2] and These all co-ordinates are present on a rectangular plane, this rectangular plane is divided into multiple smaller rectangles by performing cut parallel to the y-axis at locations given by array A[] of size X and parallel to the x-axis at locations given by array B[] of size Y, the rectangular plane will be divided into (X + 1) * (Y + 1) new rectangular pieces. Now your task for this problem is to find the minimum and maximum number of coordinates on all rectangles.

Constraints for the problem:

  • Width (W) and Height (H) of the grid: 3 <= W, H <= 10^9
  • Number of points (N): 1 <= N <= 10^5
  • Coordinates (X, Y) of points: 1 <= X, Y <= 10^5
  • Points’ coordinates (cor[i][0], cor[i][1]) are within the grid bounds: 0 < cor[i][0] < W, 0 < cor[i][1] < H
  • Length of arrays A and B: 0 < A[0] < A[1] < A[2] < … < A[X – 1] < W, 0 < B[0] < B[1] < B[2] < … < B[Y – 1] < H
  • cor[i][0] is not present in the array A, and cor[i][1] is not present in the array B.

Note: It is Guaranteed that coordinate points will never lie on the edge of any rectangle.

Examples:

Input: W = 7, H = 6, cor[][2] = {{6, 1}, {3, 1}, {4, 2}, {1, 5}, {6, 2}}, N = 5, A[] = {2, 5}, B[] = {3, 4}
Output: 0 2
Explanation: 

Red dots represent co-ordinates given by array cor[][2]

Cutting rectangle (W, H) at A[] = {2, 5} parallel to y-axis and at B[] = {3, 4} parallel to x-axis. By figure we can tell that maximum number of co-ordinates any rectangle can have is two and minimum is zero.

Input: W = 4, H = 4, cor[][2] = {{1, 1}, {3, 1}, {3, 3}, {1, 3}}, N = 4, A[] = {2}, B[] = {2}
Output:  1 1

Approach: To solve the problem follow the below idea:

Hashing can be used to solve this problem. By creating HashMap[][][][] that stores in which rectangle co-ordinate belongs. we can know the maximum and minimum number of co-ordinates in all rectangle pieces. if the HashMap size is equal to (X + 1) * (Y + 1) then each rectangle has at least one co-ordinate otherwise there are rectangles which are empty. We can simply iterate in HashMap and find rectangle which contains maximum co-ordinates and minimum co-ordinates.

Below are the steps for the above approach:

  • Create HashMap[][][][] that stores a rectangle with 4 co-ordinates its lower-left and upper-right coordinates.
  • Create two arrays arr1[] and arr2[] of size X + 2 and Y + 2.
  • Copy the array A[] in arr1[] and B[] in arr2[] with their first elements zero in both arrays and the last element W in arr1[] and H in arr2[] 
  • Iterate over all N coordinates and find the lower bound index of the given x coordinate in arr1[] and y coordinate in arr2[] and store it in ind1 and ind2 respectively.
  • Increase the counter of Hashmap[arr1[ind1 – 1]][arr1[ind1]][arr2[ind2 – 1]][arr2[ind2]] by 1 which represents this co-ordinate in current iteration belongs to rectangle with lower left co-ordinates (arr1[ind1 – 1], arr2[ind2 – 1]) and upper right co-ordinates (arr1[ind1], arr2[ind2]).
  • Declare two variables minAns initialized with INT_MAX and maxAns initialized with INT_MIN.
  • Iterate in  HashMap and find the rectangle that consists of the minimum number of coordinates and store it in minAns and find the rectangle that consists of the maximum number of coordinates and store it in maxAns.
  • if size of HashMap is equal to (X + 1) * (Y + 1) then print minAns and maxAns.
  •  else print 0 and maxAns.

Below is the implementation of the above approach: 

C++




// C++ code to implement the approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to find maximum and minimum
// number of co-ordinates in given
// rectangle after making cuts
void findMinMax(int W, int H, int cor[][2], int N,
                vector<int>& A, vector<int>& B, int X,
                int Y)
{
 
    // Creating hashmap
    map<pair<pair<int, int>, pair<int, int> >, int> HashMap;
 
    // creating edges of rectangle
    vector<int> arr1(X + 2, 0), arr2(Y + 2, 0);
 
    // copying array A to arr1
    for (int i = 1; i <= X; i++)
        arr1[i] = A[i - 1];
    arr1.back() = W;
 
    // copying array B to arr2
    for (int i = 1; i <= Y; i++)
        arr2[i] = B[i - 1];
    arr2.back() = H;
 
    // iterating each co-ordinate
    for (int i = 0; i < N; i++) {
 
        // locating x co-ordinate
        int ind1 = lower_bound(arr1.begin(), arr1.end(),
                               cor[i][0])
                   - arr1.begin();
 
        // locating y co-ordinate
        int ind2 = lower_bound(arr2.begin(), arr2.end(),
                               cor[i][1])
                   - arr2.begin();
 
        // increasing counter of HashMap
        HashMap[{ { arr1[ind1 - 1], arr1[ind1] },
                  { arr2[ind2 - 1], arr2[ind2] } }]++;
    }
 
    // max and min answer
    int minAns = INT_MAX, maxAns = INT_MIN;
 
    // iterating the HashMap
    for (auto e : HashMap) {
        minAns = min(e.second, minAns);
        maxAns = max(e.second, maxAns);
    }
 
    // if HashMap has all rectangles
    if (HashMap.size() == ((X + 1) * (Y + 1))) {
 
        // printing minAns and maxAns
        cout << minAns << " " << maxAns << endl;
    }
 
    else {
 
        // printing the minimum answer and maximum answer
        cout << 0 << " " << maxAns << endl;
    }
}
 
// Driver Code
int32_t main()
{
 
    // Input 1
    int W = 7, H = 6;
    int cor[][2] = { { 6, 1 },
                     { 3, 1 },
                     { 4, 2 },
                     { 1, 5 },
                     { 6, 2 } },
        N = 5;
    vector<int> A = { 2, 5 };
    vector<int> B = { 3, 4 };
    int X = 2, Y = 2;
 
    // Function Call
    findMinMax(W, H, cor, N, A, B, X, Y);
 
    // Input 2
    int W1 = 4, H1 = 4;
    int cor1[][2]
        = { { 1, 1 }, { 3, 1 }, { 3, 3 }, { 1, 3 } },
        N1 = 4;
    vector<int> A1 = { 2 };
    vector<int> B1 = { 2 };
    int X1 = 1, Y1 = 1;
 
    // Function Call
    findMinMax(W1, H1, cor1, N1, A1, B1, X1, Y1);
 
    return 0;
}


Java




// Java code to implement the approach
import java.util.*;
 
class GFG {
 
    // Function to find maximum and minimum
    // number of co-ordinates in given
    // rectangle after making cuts
    static void findMinMax(int W, int H, int cor[][], int N,
                           int A[], int B[], int X, int Y)
    {
 
        // Creating hashmap
        HashMap<String, Integer> HashMap = new HashMap<>();
 
        // creating edges of rectangle
        int arr1[] = new int[X + 2];
        int arr2[] = new int[Y + 2];
 
        // copying array A to arr1
        for (int i = 1; i <= X; i++)
            arr1[i] = A[i - 1];
        arr1[X + 1] = W;
 
        // copying array B to arr2
        for (int i = 1; i <= Y; i++)
            arr2[i] = B[i - 1];
        arr2[Y + 1] = H;
 
        // iterating each co-ordinate
        for (int i = 0; i < N; i++) {
 
            // locating x co-ordinate
            int ind1 = Arrays.binarySearch(arr1, cor[i][0]);
            if (ind1 < 0)
                ind1 = -ind1 - 1;
 
            // locating y co-ordinate
            int ind2 = Arrays.binarySearch(arr2, cor[i][1]);
            if (ind2 < 0)
                ind2 = -ind2 - 1;
 
            // increasing counter of HashMap
            String key = arr1[ind1 - 1] + " " + arr1[ind1]
                         + " " + arr2[ind2 - 1] + " "
                         + arr2[ind2];
            if (HashMap.containsKey(key))
                HashMap.put(key, HashMap.get(key) + 1);
            else
                HashMap.put(key, 1);
        }
 
        // max and min answer
        int minAns = Integer.MAX_VALUE, maxAns
                                        = Integer.MIN_VALUE;
 
        // iterating the HashMap
        for (Map.Entry<String, Integer> e :
             HashMap.entrySet()) {
            minAns = Math.min(e.getValue(), minAns);
            maxAns = Math.max(e.getValue(), maxAns);
        }
 
        // if HashMap has all rectangles
        if (HashMap.size() == ((X + 1) * (Y + 1))) {
 
            // printing minAns and maxAns
            System.out.println(minAns + " " + maxAns);
        }
 
        else {
 
            // printing the minimum answer and maximum
            // answer
            System.out.println(0 + " " + maxAns);
        }
    }
 
    // Driver Code
    public static void main(String[] args)
    {
 
        // Input 1
        int W = 7, H = 6;
        int cor[][] = {
            { 6, 1 }, { 3, 1 }, { 4, 2 }, { 1, 5 }, { 6, 2 }
        };
        int N = 5;
        int A[] = { 2, 5 };
        int B[] = { 3, 4 };
        int X = 2, Y = 2;
 
        // Function Call
        findMinMax(W, H, cor, N, A, B, X, Y);
 
        // Input 2
        int W1 = 4, H1 = 4;
        int cor1[][]
            = { { 1, 1 }, { 3, 1 }, { 3, 3 }, { 1, 3 } };
        int N1 = 4;
        int A1[] = { 2 };
        int B1[] = { 2 };
        int X1 = 1, Y1 = 1;
 
        // Function Call
        findMinMax(W1, H1, cor1, N1, A1, B1, X1, Y1);
    }
}
// This code is contributed by Tapesh(tapeshdua420)


Python3




# Python code to implement the approach
from bisect import bisect_left
 
# Function to find maximum and minimum
# number of co-ordinates in given
# rectangle after making cuts
def findMinMax(W, H, cor, N, A, B, X, Y):
 
    # Creating hashmap
    HashMap = {}
 
    # creating edges of rectangle
    arr1 = [0] * (X + 2)
    arr2 = [0] * (Y + 2)
 
    # copying array A to arr1
    for i in range(X):
        arr1[i + 1] = A[i]
    arr1[-1] = W
 
    # copying array B to arr2
    for i in range(Y):
        arr2[i + 1] = B[i]
    arr2[-1] = H
 
    # iterating each co-ordinate
    for i in range(N):
 
        # locating x co-ordinate
        ind1 = bisect_left(arr1, cor[i][0])
 
        # locating y co-ordinate
        ind2 = bisect_left(arr2, cor[i][1])
 
        # increasing counter of HashMap
        HashMap[(arr1[ind1 - 1], arr1[ind1], arr2[ind2 - 1], arr2[ind2])] = HashMap.get(
            (arr1[ind1 - 1], arr1[ind1], arr2[ind2 - 1], arr2[ind2]), 0) + 1
 
    # max and min answer
    minAns = float('inf')
    maxAns = float('-inf')
 
    # iterating the HashMap
    for e in HashMap:
        minAns = min(HashMap[e], minAns)
        maxAns = max(HashMap[e], maxAns)
 
    # if HashMap has all rectangles
    if len(HashMap) == ((X + 1) * (Y + 1)):
 
        # printing minAns and maxAns
        print(minAns, maxAns)
 
    else:
 
        # printing the minimum answer and maximum answer
        print(0, maxAns)
 
 
# Driver Code
if __name__ == '__main__':
 
    # Input 1
    W = 7
    H = 6
    cor = [[6, 1], [3, 1], [4, 2], [1, 5], [6, 2]]
    N = 5
    A = [2, 5]
    B = [3, 4]
    X = 2
    Y = 2
 
    # Function Call
    findMinMax(W, H, cor, N, A, B, X, Y)
 
    # Input 2
    W1 = 4
    H1 = 4
    cor1 = [[1, 1], [3, 1], [3, 3], [1, 3]]
    N1 = 4
    A1 = [2]
    B1 = [2]
    X1 = 1
    Y1 = 1
 
    # Function Call
    findMinMax(W1, H1, cor1, N1, A1, B1, X1, Y1)
 
# This code is contributed by Tapesh(tapeshdua420)


C#




using System;
using System.Collections.Generic;
 
class GFG
{
    // Function to find maximum and minimum
    // number of co-ordinates in given
    // rectangle after making cuts
    static void FindMinMax(int W, int H, int[][] cor, int N,
                           int[] A, int[] B, int X, int Y)
    {
        // Creating dictionary
        Dictionary<string, int> dictionary = new Dictionary<string, int>();
 
        // creating edges of rectangle
        int[] arr1 = new int[X + 2];
        int[] arr2 = new int[Y + 2];
 
        // copying array A to arr1
        for (int i = 1; i <= X; i++)
            arr1[i] = A[i - 1];
        arr1[X + 1] = W;
 
        // copying array B to arr2
        for (int i = 1; i <= Y; i++)
            arr2[i] = B[i - 1];
        arr2[Y + 1] = H;
 
        // iterating each co-ordinate
        for (int i = 0; i < N; i++)
        {
            // locating x co-ordinate
            int ind1 = Array.BinarySearch(arr1, cor[i][0]);
            if (ind1 < 0)
                ind1 = ~ind1;
 
            // locating y co-ordinate
            int ind2 = Array.BinarySearch(arr2, cor[i][1]);
            if (ind2 < 0)
                ind2 = ~ind2;
 
            // increasing counter of dictionary
            string key = arr1[ind1 - 1] + " " + arr1[ind1]
                         + " " + arr2[ind2 - 1] + " "
                         + arr2[ind2];
            if (dictionary.ContainsKey(key))
                dictionary[key]++;
            else
                dictionary[key] = 1;
        }
 
        // max and min answer
        int minAns = int.MaxValue, maxAns = int.MinValue;
 
        // iterating the dictionary
        foreach (var entry in dictionary)
        {
            minAns = Math.Min(entry.Value, minAns);
            maxAns = Math.Max(entry.Value, maxAns);
        }
 
        // if dictionary has all rectangles
        if (dictionary.Count == ((X + 1) * (Y + 1)))
        {
            // printing minAns and maxAns
            Console.WriteLine(minAns + " " + maxAns);
        }
        else
        {
            // printing the minimum answer and maximum
            // answer
            Console.WriteLine(0 + " " + maxAns);
        }
    }
 
    // Driver Code
    public static void Main(string[] args)
    {
        // Input 1
        int W = 7, H = 6;
        int[][] cor = {
            new int[] {6, 1}, new int[] {3, 1}, new int[] {4, 2}, new int[] {1, 5}, new int[] {6, 2}
        };
        int N = 5;
        int[] A = { 2, 5 };
        int[] B = { 3, 4 };
        int X = 2, Y = 2;
 
        // Function Call
        FindMinMax(W, H, cor, N, A, B, X, Y);
 
        // Input 2
        int W1 = 4, H1 = 4;
        int[][] cor1 = {
            new int[] {1, 1}, new int[] {3, 1}, new int[] {3, 3}, new int[] {1, 3}
        };
        int N1 = 4;
        int[] A1 = { 2 };
        int[] B1 = { 2 };
        int X1 = 1, Y1 = 1;
 
        // Function Call
        FindMinMax(W1, H1, cor1, N1, A1, B1, X1, Y1);
    }
}


Javascript




function bisect_left(arr, target) {
    // Binary search to find the leftmost index where target can be inserted in the sorted array
    let left = 0;
    let right = arr.length;
 
    while (left < right) {
        const mid = Math.floor((left + right) / 2);
        if (arr[mid] < target) {
            left = mid + 1;
        } else {
            right = mid;
        }
    }
 
    return left;
}
 
function findMinMax(W, H, cor, N, A, B, X, Y) {
    const HashMap = {};
    const arr1 = new Array(X + 2).fill(0);  // Array for X coordinates
    const arr2 = new Array(Y + 2).fill(0);  // Array for Y coordinates
 
    // Copying array A to arr1
    for (let i = 0; i < X; i++) {
        arr1[i + 1] = A[i];
    }
    arr1[X + 1] = W;  // Set the last element as the width of the rectangle
 
    // Copying array B to arr2
    for (let i = 0; i < Y; i++) {
        arr2[i + 1] = B[i];
    }
    arr2[Y + 1] = H;  // Set the last element as the height of the rectangle
 
    // Iterate through each coordinate
    for (let i = 0; i < N; i++) {
        const ind1 = bisect_left(arr1, cor[i][0]);  // Locate x coordinate
        const ind2 = bisect_left(arr2, cor[i][1]);  // Locate y coordinate
        const key = [arr1[ind1 - 1], arr1[ind1], arr2[ind2 - 1], arr2[ind2]].toString();
        // Increase the counter for the coordinate in HashMap
        HashMap[key] = (HashMap[key] || 0) + 1;
    }
 
    let minAns = Infinity;
    let maxAns = -Infinity;
 
    // Iterate through the HashMap to find min and max answers
    for (const e in HashMap) {
        const count = HashMap[e];
        minAns = Math.min(count, minAns);
        maxAns = Math.max(count, maxAns);
    }
 
    if (Object.keys(HashMap).length === (X + 1) * (Y + 1)) {
        console.log("Minimum number of coordinates:", minAns,
                    "Maximum number of coordinates:", maxAns);
    } else {
        console.log("Minimum number of coordinates:", 0,
                    "Maximum number of coordinates:", maxAns);
    }
}
 
// Driver Code
const W = 7;
const H = 6;
const cor = [[6, 1], [3, 1], [4, 2], [1, 5], [6, 2]];
const N = 5;
const A = [2, 5];
const B = [3, 4];
const X = 2;
const Y = 2;
findMinMax(W, H, cor, N, A, B, X, Y);
 
const W1 = 4;
const H1 = 4;
const cor1 = [[1, 1], [3, 1], [3, 3], [1, 3]];
const N1 = 4;
const A1 = [2];
const B1 = [2];
const X1 = 1;
const Y1 = 1;
findMinMax(W1, H1, cor1, N1, A1, B1, X1, Y1);


Output

0 2
1 1








Time Complexity: O(N*logN)  
Auxiliary Space: O(N)

Related Articles:



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads