Pairs with same Manhattan and Euclidean distance
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: 2
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)| = 1Input: N = 3, Points = { {1, 1}, {2, 3}, {1, 1} }
Output: 0
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,
- Map X, where X[xi] stores the number of points having their x-coordinate equal to xi
- Map Y, where Y[yi] stores the number of points having their y-coordinate equal to yi
- 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> |
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.
Please Login to comment...