Open In App

Pairs with same Manhattan and Euclidean distance

Last Updated : 30 Jul, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

In a given Cartesian plane, there are N points. The task is to find the Number of Pairs of points(A, B) such that 
 

  • Point A and Point B do not coincide.
  • Manhattan Distance and the Euclidean Distance between the points should be equal.

Note: Pair of 2 points(A, B) is considered same as Pair of 2 points(B, A).

Manhattan Distance = |x2-x1|+|y2-y1|
Euclidean Distance = ((x2-x1)^2 + (y2-y1)^2)^0.5 where points are (x1, y1) and (x2, y2).

Examples: 

Input: N = 3, Points = {{1, 2}, {2, 3}, {1, 3}} 
Output:
Pairs are: 
1) (1, 2) and (1, 3) 
Euclidean distance of (1, 2) and (1, 3) = &root;((1 - 1)2 + (3 - 2)2) = 1 
Manhattan distance of (1, 2) and (1, 3) = |(1 - 1)| + |(2 - 3)| = 1
2) (1, 3) and (2, 3) 
Euclidean distance of (1, 3) and (2, 3) = &root;((1 - 2)2 + (3 - 3)2) = 1 
Manhattan distance of (1, 3) and (2, 3) = |(1 - 2)| + |(3 - 3)| = 1

Input: N = 3, Points = { {1, 1}, {2, 3}, {1, 1} } 
Output:
Here none of the pairs satisfy the above two conditions


Approach: On solving the equation 

|x2-x1|+|y2-y1| = sqrt((x2-x1)^2+(y2-y1)^2)

we get , x2 = x1 or y2 = y1.

Consider 3 maps, 

  1. Map X, where X[xi] stores the number of points having their x-coordinate equal to xi 
  2. Map Y, where Y[yi] stores the number of points having their y-coordinate equal to yi 
  3. Map XY, where XY[(Xi, Yi)] stores the number of points coincident with point (xi, yi)

Now, 
Let Xans be the Number of pairs with same X-coordinates = X[xi]2 for all distinct xi
Let Yans be the Number of pairs with same Y-coordinates = Y[xi]2 for all distinct yi 
Let XYans be the Number of coincident points = XY[{xi, yi}]2 for all distinct points (xi, yi)
Thus the required answer = Xans + Yans - XYans

Below is the implementation of the above approach:

C++
// C++ implementation of the above approach
#include <bits/stdc++.h>
using namespace std;

// Function to return the number of non coincident
// pairs of points with manhattan distance
// equal to euclidean distance
int findManhattanEuclidPair(pair<int, int> arr[], int n)
{
    // To store frequency of all distinct Xi
    map<int, int> X;

    // To store Frequency of all distinct Yi
    map<int, int> Y;

    // To store Frequency of all distinct
    // points (Xi, Yi);
    map<pair<int, int>, int> XY;

    for (int i = 0; i < n; i++) {
        int xi = arr[i].first;
        int yi = arr[i].second;

        // Hash xi coordinate
        X[xi]++;

        // Hash yi coordinate
        Y[yi]++;

        // Hash the point (xi, yi)
        XY[arr[i]]++;
    }

    int xAns = 0, yAns = 0, xyAns = 0;

    // find pairs with same Xi
    for (auto xCoordinatePair : X) {
        int xFrequency = xCoordinatePair.second;

        // calculate ((xFrequency) C2)
        int sameXPairs
            = (xFrequency * (xFrequency - 1)) / 2;
        xAns += sameXPairs;
    }

    // find pairs with same Yi
    for (auto yCoordinatePair : Y) {
        int yFrequency = yCoordinatePair.second;

        // calculate ((yFrequency) C2)
        int sameYPairs
            = (yFrequency * (yFrequency - 1)) / 2;
        yAns += sameYPairs;
    }

    // find pairs with same (Xi, Yi)
    for (auto XYPair : XY) {
        int xyFrequency = XYPair.second;

        // calculate ((xyFrequency) C2)
        int samePointPairs
            = (xyFrequency * (xyFrequency - 1)) / 2;
        xyAns += samePointPairs;
    }

    return (xAns + yAns - (2 * xyAns));
    /*    we are subtracting 2 * xyAns because we have counted
       let say A,B coinciding points two times in xAns and
       yAns which should not be add to the final answer so
       we are subtracting xyAns 2 times. */
}

// Driver Code
int main()
{
    pair<int, int> arr[]
        = { { 1, 2 }, { 1, 2 }, { 4, 3 }, { 1, 3 } };
    int n = sizeof(arr) / sizeof(arr[0]);

    cout << findManhattanEuclidPair(arr, n) << endl;
    return 0;
}
Java
// Java implementation of the above approach
import java.util.*;

public class GFG
{
  
  // Function to return the number of non coincident
  // pairs of points with manhattan distance
  // equal to euclidean distance
  static int findManhattanEuclidPair(int[][] arr, int n)
  {
    
    // To store frequency of all distinct Xi
    Map<Integer, Integer> X = new HashMap<Integer, Integer>();

    // To store Frequency of all distinct Yi
    Map<Integer, Integer> Y = new HashMap<Integer, Integer>();

    // To store Frequency of all distinct
    // points (Xi, Yi);
    Map<List<Integer>, Integer> XY = new HashMap<List<Integer>, Integer>();

    for (int i = 0; i < n; i++) {
      int xi = arr[i][0];
      int yi = arr[i][1];

      // Hash xi coordinate
      if (!X.containsKey(xi))
        X.put(xi, 0);
      X.put(xi, X.get(xi) + 1);

      // Hash yi coordinate
      if (!Y.containsKey(yi))
        Y.put(yi, 0);
      Y.put(yi, Y.get(yi) + 1);

      // Hash the point (xi, yi)
      if (!XY.containsKey(Arrays.asList(xi, yi)))
        XY.put(Arrays.asList(xi, yi), 0);
      XY.put( Arrays.asList(xi, yi), XY.get(Arrays.asList(xi, yi)) + 1);
    }

    int xAns = 0, yAns = 0, xyAns = 0;

    // find pairs with same Xi
    for (Map.Entry<Integer, Integer> xCoordinatePair : X.entrySet())
    {
      int xFrequency = xCoordinatePair.getValue();

      // calculate ((xFrequency) C2)
      int sameXPairs
        = (xFrequency * (xFrequency - 1)) / 2;
      xAns += sameXPairs;
    }

    // find pairs with same Yi
    for (Map.Entry<Integer, Integer> yCoordinatePair : Y.entrySet()) {
      int yFrequency = yCoordinatePair.getValue();

      // calculate ((yFrequency) C2)
      int sameYPairs
        = (yFrequency * (yFrequency - 1)) / 2;
      yAns += sameYPairs;
    }

    // find pairs with same (Xi, Yi)
    for (Map.Entry<List<Integer>, Integer> XYPair : XY.entrySet())
    {
      int xyFrequency = XYPair.getValue();

      // calculate ((xyFrequency) C2)
      int samePointPairs
        = (xyFrequency * (xyFrequency - 1)) / 2;
      xyAns += samePointPairs;
    }

    return (xAns + yAns - (2 * xyAns));
    /*    we are subtracting 2 * xyAns because we have counted
           let say A,B coinciding points two times in xAns and
           yAns which should not be add to the final answer so
           we are subtracting xyAns 2 times. */
  }

  // Driver Code
  public static void main(String[] args)
  {
    int[][] arr
      = { { 1, 2 }, { 1, 2 }, { 4, 3 }, { 1, 3 } };
    int n = arr.length;

    System.out.println(findManhattanEuclidPair(arr, n));
  }
}

// This code is contributed by phasing17
Python3
# Python3 implementation of the 
# above approach 
from collections import defaultdict

# Function to return the number of 
# non coincident pairs of points with 
# manhattan distance equal to 
# euclidean distance 
def findManhattanEuclidPair(arr, n): 

    # To store frequency of all distinct Xi 
    X = defaultdict(lambda:0) 

    # To store Frequency of all distinct Yi 
    Y = defaultdict(lambda:0) 

    # To store Frequency of all distinct 
    # points (Xi, Yi) 
    XY = defaultdict(lambda:0) 

    for i in range(0, n): 
        xi = arr[i][0]
        yi = arr[i][1] 

        # Hash xi coordinate 
        X[xi] += 1

        # Hash yi coordinate 
        Y[yi] += 1

        # Hash the point (xi, yi) 
        XY[tuple(arr[i])] += 1
    
    xAns, yAns, xyAns = 0, 0, 0

    # find pairs with same Xi 
    for xCoordinatePair in X: 
        xFrequency = X[xCoordinatePair]

        # calculate ((xFrequency) C2) 
        sameXPairs = (xFrequency * 
                     (xFrequency - 1)) // 2
        xAns += sameXPairs 
    
    # find pairs with same Yi 
    for yCoordinatePair in Y: 
        yFrequency = Y[yCoordinatePair] 

        # calculate ((yFrequency) C2) 
        sameYPairs = (yFrequency * 
                     (yFrequency - 1)) // 2
        yAns += sameYPairs 

    # find pairs with same (Xi, Yi) 
    for XYPair in XY: 
        xyFrequency = XY[XYPair] 
    
        # calculate ((xyFrequency) C2) 
        samePointPairs = (xyFrequency * 
                         (xyFrequency - 1)) // 2
        xyAns += samePointPairs 
    
    return (xAns + yAns - 2 * xyAns) 
  #    we are subtracting 2 * xyAns because we have counted let say A,B coinciding points two times 
   #  in xAns and yAns which should not be add to the final answer so we are subtracting xyAns 2 times. 

# Driver Code 
if __name__ == "__main__":

    arr = [[1, 2], [1,2], [4, 3], [1, 3]] 
    
    n = len(arr) 

    print(findManhattanEuclidPair(arr, n)) 
    
# This code is contributed by Rituraj Jain
C#
// C# implementation of the above approach
using System;
using System.Collections.Generic;

class GFG
{
  
  // Function to return the number of non coincident
  // pairs of points with manhattan distance
  // equal to euclidean distance
  static int findManhattanEuclidPair(int[, ] arr, int n)
  {
    
    // To store frequency of all distinct Xi
    Dictionary<int, int> X = new Dictionary<int, int>();

    // To store Frequency of all distinct Yi
    Dictionary<int, int> Y = new Dictionary<int, int>();

    // To store Frequency of all distinct
    // points (Xi, Yi);
    var XY = new Dictionary<(int first, int second), int>();

    for (int i = 0; i < n; i++) {
      int xi = arr[i, 0];
      int yi = arr[i, 1];

      // Hash xi coordinate
      if (!X.ContainsKey(xi))
        X[xi] = 0;
      X[xi]++;

      // Hash yi coordinate
      if (!Y.ContainsKey(yi))
        Y[yi] = 0;
      Y[yi]++;

      // Hash the point (xi, yi)
      if (!XY.ContainsKey((xi, yi)))
        XY[(xi, yi)] = 0;
      XY[(xi, yi)]++;
    }

    int xAns = 0, yAns = 0, xyAns = 0;

    // find pairs with same Xi
    foreach (var xCoordinatePair in X) {
      int xFrequency = xCoordinatePair.Value;

      // calculate ((xFrequency) C2)
      int sameXPairs
        = (xFrequency * (xFrequency - 1)) / 2;
      xAns += sameXPairs;
    }

    // find pairs with same Yi
    foreach (var yCoordinatePair in Y) {
      int yFrequency = yCoordinatePair.Value;

      // calculate ((yFrequency) C2)
      int sameYPairs
        = (yFrequency * (yFrequency - 1)) / 2;
      yAns += sameYPairs;
    }

    // find pairs with same (Xi, Yi)
    foreach (var XYPair in XY) {
      int xyFrequency = XYPair.Value;

      // calculate ((xyFrequency) C2)
      int samePointPairs
        = (xyFrequency * (xyFrequency - 1)) / 2;
      xyAns += samePointPairs;
    }

    return (xAns + yAns - (2 * xyAns));
    /*    we are subtracting 2 * xyAns because we have counted
           let say A,B coinciding points two times in xAns and
           yAns which should not be add to the final answer so
           we are subtracting xyAns 2 times. */
  }

  // Driver Code
  public static void Main(string[] args)
  {
    int[, ] arr
      = { { 1, 2 }, { 1, 2 }, { 4, 3 }, { 1, 3 } };
    int n = arr.GetLength(0);

    Console.WriteLine(findManhattanEuclidPair(arr, n));
  }
}

// This code is contributed by pphasing17
JavaScript
<script>
// JavaScript implementation of the 
// above approach 
function getVal(dict, val)
{
    if (dict.hasOwnProperty(val))
        return dict[val]
    return 0
}

// Function to return the number of 
// non coincident pairs of points with 
// manhattan distance equal to 
// euclidean distance 
function findManhattanEuclidPair(arr, n)
{
    // To store frequency of all distinct Xi 
    let X = {}

    // To store Frequency of all distinct Yi 
    let Y = {}

    // To store Frequency of all distinct 
    // points (Xi, Yi) 
    let XY = {}

    for (var i = 0; i < n; i++)
    {
        let xi = arr[i][0]
        let yi = arr[i][1] 

        // Hash xi coordinate 
        X[xi] = 1 + getVal(X, xi)

        // Hash yi coordinate 
        Y[yi] = 1 + getVal(Y, yi)

        // Hash the point (xi, yi) 
        XY[arr[i].join("#")] = 1 + getVal(XY, arr[i].join("#"))
    }
    
    let xAns = 0
    let yAns = 0
    let xyAns = 0

    // find pairs with same Xi 
    for (const [xCoordinatePair, xFrequency] of  Object.entries(X))
    {
        // calculate ((xFrequency) C2) 
        sameXPairs = Math.floor((xFrequency * 
                     (xFrequency - 1)) / 2)
        xAns += sameXPairs 
    }
    
    // find pairs with same Yi 
    for (const [yCoordinatePair, yFrequency] of Object.entries(Y)) 
    {
        // calculate ((yFrequency) C2) 
        sameYPairs = Math.floor((yFrequency * 
                     (yFrequency - 1)) / 2)

        yAns += sameYPairs 
    }
    
    // find pairs with same (Xi, Yi) 
    for (const [XYPair, xyFrequency] of Object.entries(XY)) 
    {
    
        // calculate ((xyFrequency) C2) 
        samePointPairs = Math.floor((xyFrequency * 
                         (xyFrequency - 1)) / 2)
        xyAns += samePointPairs 
    }
    
    return (xAns + yAns - 2 * xyAns) 
  //   we are subtracting 2 * xyAns because 
  // we have counted let say A,B coinciding points two times 
   //  in xAns and yAns which should not be 
   // add to the final answer so we are subtracting xyAns 2 times. 
}

// Driver Code 
let arr = [[1, 2], [1,2], [4, 3], [1, 3]] 
let n = arr.length 

console.log(findManhattanEuclidPair(arr, n)) 
  
// This code is contributed by phasing17

</script>

Output
3

Complexity Analysis:

  • Time Complexity: O(NlogN), where N is the number of points 
  • Space Complexity: O(N), since N extra space has been taken.

Next Article

Similar Reads