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)| = 1
Input: 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,
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; } |
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 |
3
Time Complexity: O(NlogN), where N is the number of points
Space Complexity: O(N)