[算法]距离问题

距离问题

又名: Pairs with same Manhattan and Euclidean distance

问题地址

问题描述

Description

In a given cartesian plane, there are N points. We need to find the Number of Pairs of points(A,B) such that

  1. Point A and Point B do not coincide.
  2. 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).

Constraints:1<=T <= 50, 1<=N <= 2*10 ^ 5, 0<=(|Xi|, |Yi|) <= 10^9

Input

First Line Consist of T - number of test cases. For each Test case:First Line consist of N , Number of points. Next line contains N pairs contains two integers Xi and Yi,i.e, X coordinate and the Y coordinate of a Point

Output

Print the number of pairs as asked above.

Sample Input 1

1
2
1 1
7 5

Sample Output 1

0
题目解析

二维平面内,给定一堆不重复的点,求这些点两两组合后曼哈顿距离等于欧式距离的个数,

Manhattan Distance = |x2-x1|+|y2-y1|

Euclidean Distance = ((x2-x1)2 + (y2-y1)2)0.5

思路解析

令曼哈顿距离等于欧式距离,实际上是求下个式子的解:
∣ x 2 − x 1 ∣ + ∣ y 2 − y 1 ∣ = s q r t ( ( x 2 − x 1 ) 2 + ( y 2 − y 1 ) 2 ) |x2-x1|+|y2-y1| = sqrt((x2-x1)^2+(y2-y1)^2) x2x1+y2y1=sqrt((x2x1)2+(y2y1)2)

解 得 :   x 2 = x 1   o r   y 2 = y 1 解得:\ x2 = x1\ or\ y2 = y1 : x2=x1 or y2=y1

集 合 的 思 想 : ( x 2 = x 1   o r   y 2 = y 1 ) = ( x 2 = x 1 ) + ( y 2 = y 1 ) − ( x 2 = x 1   a n d   y 2 = y 1 ) 集合的思想:\\ (x2 = x1\ or\ y2 = y1 ) = (x2 = x1 ) + (y2 = y1) - (x2 = x1\ and\ y2 = y1 ) :(x2=x1 or y2=y1)=(x2=x1)+(y2=y1)(x2=x1 and y2=y1)

因此解题步骤如下

  1. 统计横坐标相等的点的个数X_num
  2. 统计纵坐标相等的点的个数Y_num
  3. 统计横纵坐标相等的点的个数XY_num
  4. 假设有X_num 个点横坐标相等,那可以组成的n * (n-1) /2对点X_pair = X_num* n * (n-1) /2
  5. 答案就是X_pair + Y_pair -XY_pair
代码实现(python)
from collections import defaultdict

if __name__ == '__main__':
    case_num = int(input())
    for i in range(case_num):
        dict_x = defaultdict(int)  # 初始化一个默认值为0的map
        dict_y = defaultdict(int)
        dict_xy = defaultdict(int)
        point_num = int(input())
        for j in range(point_num):
            p = [int(x) for x in input().strip().split(" ")]
            dict_x[p[0]] += 1
            dict_y[p[1]] += 1
            dict_xy[tuple(p)] += 1
        x_pair_num = 0
        y_pair_num = 0
        xy_pair_num = 0
        for k, v in dict_x.items():
            x_pair_num += v * (v - 1) // 2
        for k, v in dict_y.items():
            y_pair_num += v * (v - 1) // 2
        for k, v in dict_xy.items():
            xy_pair_num += v * (v - 1) // 2
        print(x_pair_num + y_pair_num - xy_pair_num)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值