Open In App

Count squares of unique dimensions possible from given Straight Lines parallel to the axes

Improve
Improve
Like Article
Like
Save
Share
Report

Given two arrays X[] and Y[] consisting of N and M integers such that there are N lines parallel to the y-axis and M lines parallel to the x-axis, the task is to find the total number of squares having unique dimensions that can be generated from the given straight lines.

Each integer(say a) in the array X[] denotes lines having equation x = a, parallel to 
y-axis
Each integer(say b) in the array Y[] denotes lines having equation y = b, parallel to 
x-axis

Examples:

Input: X[] = {1, 3, 7}, Y[] = {1, 2, 4, 6}
Output:
Explanation:
3 lines are parallel to y-axis for x = 1, x = 3 and x = 7. 
4 lines are parallel to x-axis for y = 2, y = 4, y = 6 and y = 1. 

From the above figure, there are two possible squares of unique dimensions that are possible:
1) square ABDC (x = 1, x = 3, y = 4, y = 6), side = 2 units.
2) square BGHF (x = 3, x = 7, y = 2, y = 6), side = 4 units.

Input: X[] = {2, 6, 7, 8}, Y[] = {1, 3, 5, 7}
Output: 3

Naive Approach: The simplest approach is to check for every possible vertical dimension if there exists an equal horizontal dimension. The time complexity of this approach can be reduced with the help of the map. By using a map, we can get all the different vertical/horizontal dimensions. i>Time Complexity: O((N2)*log N)
Auxiliary Space: O(N)

Efficient Approach: To optimize the above approach, the idea is to generate all possible dimensions with the help of bitsets. Follow the steps below to solve this problem:

  • Initialize bitsets for horizontal and vertical lines from the array X[] and Y[] respectively.
  • Set positions of vertical and horizontal lines in the bitset.
  • Maintain another bitset hdiff and vdiff that store the different possible dimensions of squares. The dimensions can be obtained by shifting the set bits in the original bitset.
  • After the above steps, the unique count of squares is the count of the common element in hdiff and vdiff which is calculated by (hdiff&vdiff).count().

Below is the implementation of the above approach:

C++




// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
const int N = 100;
 
// Function to find the number of
// unique squares
int countSquares(int* hor, int* ver,
                 int n, int m)
{
    // Positions of the X[] and Y[]
    // are set in the bitsets hpos
    // and vpos respectively
    bitset<N> hpos, vpos;
 
    for (int i = 0; i < n; ++i) {
        hpos.set(hor[i]);
    }
    for (int i = 0; i < m; ++i) {
        vpos.set(ver[i]);
    }
 
    // Stores all possible sides of the
    // square are set in the bitsets
    // having difference hdiff & vdiff
    bitset<N> hdiff, vdiff;
 
    for (int i = 0; i < n; ++i) {
        hdiff = hdiff | (hpos >> hor[i]);
    }
    for (int i = 0; i < m; ++i) {
        vdiff = vdiff | (vpos >> ver[i]);
    }
 
    // Finding the number of square
    // sides which are common to both
    int common = (hdiff & vdiff).count();
 
    // Print the count of squares
    cout << common - 1;
}
 
// Driver Code
int main()
{
    // Given horizontal line segments
    int X[] = { 1, 3, 7 };
 
    // Given vertical line segments
    int Y[] = { 1, 2, 4, 6 };
 
    int N = (sizeof(X) / sizeof(X[0]));
    int M = (sizeof(Y) / sizeof(Y[0]));
 
    // Function Call
    countSquares(X, Y, N, M);
 
    return 0;
}


Java




// Java program for the above approach
import java.util.*;
 
class GFG
{
  static int N = 100;
 
  // Function to find the number of
  // unique squares
  static void countSquares(int[] hor, int[] ver, int n,int m)
  {
 
    // Positions of the X[] and Y[]
    // are set in the bitsets hpos
    // and vpos respectively
    var hpos = 0;
    var vpos = 0;
 
    for (var i = 0; i < n; i++)
      hpos |= (1 << hor[i]);
 
    for (var i = 0; i < m; i++)
      vpos |= (1 << ver[i]);
 
    // Stores all possible sides of the
    // square are set in the bitsets
    // having difference hdiff & vdiff
    var hdiff = 0;
    var vdiff = 0;
 
    for (var i = 0; i < n; i++)
      hdiff = hdiff | (hpos >> hor[i]);
 
    for (var i = 0; i < m; i++)
      vdiff = vdiff | (vpos >> ver[i]);
 
    // Finding the number of square
    // sides which are common to both
    var common = 0;
    var res = hdiff & vdiff;
    while (res > 0)
    {
      if ((res & 1) == 1)
        common++;
      res = (int)(res / 2);
    }
 
    // Print the count of squares
    System.out.print(common - 1);
  }
 
  // Driver Code
 
  public static void main(String[] args)
  {
    // Given horizontal line segments
    int[] X =  {1, 3, 7 };
 
    // Given vertical line segments
    int[] Y =  {1, 2, 4, 6};
 
    N = X.length;
    var M  = Y.length;
 
    // Function Call
    countSquares(X, Y, N, M);
  }
}
 
// This code is contributed by phasing17


Python3




# Python3 program for the above approach
N = 100;
 
# Function to find the number of
# unique squares
def countSquares(hor, ver, n, m):
 
    # Positions of the X[] and Y[]
    # are set in the bitsets hpos
    # and vpos respectively
    hpos, vpos = 0, 0;
     
    for i in range(n):
        hpos |= (1 << hor[i])
     
    for i in range(m):
        vpos |= (1 << ver[i])
     
    # Stores all possible sides of the
    # square are set in the bitsets
    # having difference hdiff & vdiff
    hdiff, vdiff = 0, 0;
 
    for i in range(n):
        hdiff = hdiff | (hpos >> hor[i])
     
    for i in range(m):
        vdiff = vdiff | (vpos >> ver[i])
     
    # Finding the number of square
    # sides which are common to both
    common = bin(hdiff & vdiff).count("1");
 
    # Print the count of squares
    print(common - 1);
 
# Driver Code
 
# Given horizontal line segments
X =  [1, 3, 7 ];
 
# Given vertical line segments
Y =  [1, 2, 4, 6]
 
N = len(X)
= len(Y)
 
# Function Call
countSquares(X, Y, N, M);
 
# This code is contributed by phasing17


C#




// C# program for the above approach
using System;
using System.Collections.Generic;
 
class GFG
{
  static int N = 100;
 
  // Function to find the number of
  // unique squares
  static void countSquares(int[] hor, int[] ver, int n,int m)
  {
 
    // Positions of the X[] and Y[]
    // are set in the bitsets hpos
    // and vpos respectively
    var hpos = 0;
    var vpos = 0;
 
    for (var i = 0; i < n; i++)
      hpos |= (1 << hor[i]);
 
    for (var i = 0; i < m; i++)
      vpos |= (1 << ver[i]);
 
    // Stores all possible sides of the
    // square are set in the bitsets
    // having difference hdiff & vdiff
    var hdiff = 0;
    var vdiff = 0;
 
    for (var i = 0; i < n; i++)
      hdiff = hdiff | (hpos >> hor[i]);
 
    for (var i = 0; i < m; i++)
      vdiff = vdiff | (vpos >> ver[i]);
 
    // Finding the number of square
    // sides which are common to both
    var common = 0;
    var res = hdiff & vdiff;
    while (res > 0)
    {
      if ((res & 1) == 1)
        common++;
      res = (int)(res / 2);
    }
 
    // Print the count of squares
    Console.Write(common - 1);
  }
 
  // Driver Code
 
  public static void Main(string[] args)
  {
    // Given horizontal line segments
    int[] X =  {1, 3, 7 };
 
    // Given vertical line segments
    int[] Y =  {1, 2, 4, 6};
 
    N = X.Length;
    var M  = Y.Length;
 
    // Function Call
    countSquares(X, Y, N, M);
  }
}
 
// This code is contributed by phasing17


Javascript




// JS program for the above approach
let N = 100;
 
// Function to find the number of
// unique squares
function countSquares(hor, ver, n, m)
{
 
    // Positions of the X[] and Y[]
    // are set in the bitsets hpos
    // and vpos respectively
    let hpos = 0
    let vpos = 0
     
    for (var i = 0; i < n; i++)
        hpos |= (1 << hor[i])
     
    for (var i = 0; i < m; i++)
        vpos |= (1 << ver[i])
     
    // Stores all possible sides of the
    // square are set in the bitsets
    // having difference hdiff & vdiff
    let hdiff = 0
    let vdiff = 0
 
    for (var i = 0; i < n; i++)
        hdiff = hdiff | (hpos >> hor[i])
     
    for (var i = 0; i < m; i++)
        vdiff = vdiff | (vpos >> ver[i])
     
    // Finding the number of square
    // sides which are common to both
    let common = 0;
    let res = hdiff & vdiff
    while (res > 0)
    {
        if (res & 1)
            common++;
        res = Math.floor(res / 2)
    }
 
    // Print count of squares
    console.log(common - 1);
}
 
// Driver Code
 
// Given horizontal line segments
let X =  [1, 3, 7 ];
 
// Given vertical line segments
let Y =  [1, 2, 4, 6]
 
N = X.length
let M  = Y.length
 
// Function Call
countSquares(X, Y, N, M);
 
// This code is contributed by phasing17


Output:

2

Time Complexity: O(N + M)
Auxiliary Space: O(maxE), where maxE is the maximum element among both the arrays X[] and Y[].



Last Updated : 29 Dec, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads