版权声明:AnFany https://blog.csdn.net/qq_32882309/article/details/88715122
P92.4 DiamondsCount
Given points on a plane, count the number of sets of four points that form regular diamonds.
- P92.4 菱形个数
给定平面上的点,计算这些点可以构成不同的菱形的个数
在一个平面上有N个不同的点。计算可以使用这些点作为顶点构建的不同菱形的数目(如果两个菱形的顶点集不同,则这两个菱形视为不同)。注意:这些顶点不能是同一个,并且保证菱形的对角线要与坐标轴平行。
编写函数:
def solution(X, Y)
给定两个数组X和Y,每个数组包含N个整数,代表N个点,其中(X[K],Y[K])是第K个点的坐标,返回平面上的不同菱形的数目。
例如,如果N=7时的表示坐标的数组,X=[1,1,2,2,2,3,3]和Y=[3,4,1,3,5,3,4],函数应该返回2,因为可以找到两个菱形,如下图所示:
给定数组:X=[1,2,3,3,2,1],Y=[1,1,2,2,2],函数应该返回0,因为不能构成满足条件的菱形:
假定:
- N是区间[4,1500]内的整数;
- 数组X,Y的每个元素都是区间[0,N−1]内的整数;
- 给定的N个点都是两两不同的。
- 解题思路
因为菱形的对角线需要和坐标轴平行,因此组成菱形的四个点需要满足下面的条件:
- 上下2个点的横坐标是一样的;
- 左右2个点的纵坐标是一样的;
- 上下2个点的纵坐标和的均值恰好是左右2个点的纵坐标;
- 左右2个点的横坐标和的均值恰好是上下2个点的横坐标;
- Python3代码
# -*- coding:utf-8 -*-
# &Author AnFany
# Lesson 92:Tasks from Indeed Prime 2016 College Coders challenge
# P 92.4 DiamondsCount
def solution(X, Y):
"""
给出平面上的点,得出满足条件的不同菱形的个数
:param X: 点的横坐标
:param Y: 点的纵坐标
:return: 不同菱形的个数
"""
x_dict = {} # 横坐标为键,纵坐标为值的字典
y_dict = {} # 纵坐标为键,横坐标为值的字典
for x, y in zip(X, Y):
if x in x_dict:
x_dict[x].append(y)
else:
x_dict[x] = [y]
if y in y_dict:
y_dict[y].append(x)
else:
y_dict[y] = [x]
# 不同的x或者y都必须大于2个,才可能组成满足条件的菱形
if len(x_dict) <= 2 or len(y_dict) <= 2:
return 0
# 开始判断是否可以构成菱形
count = 0
for i in x_dict: # 遍历横坐标
point_count = x_dict[i] # 这个横坐标上的点最少为2个,才可能构建菱形
if len(point_count) >= 2:
for o in range(len(point_count) - 1):
for t in range(o + 1, len(point_count)):
y_sum = point_count[o] + point_count[t] # 开始计算纵坐标的均值,需要为整数
if y_sum % 2 == 0:
y_value = y_sum // 2
if y_value in y_dict: # 纵坐标存在
y_point = y_dict[y_value] # 该纵坐标对应的横坐标序列
if len(y_point) >= 2: # 这个纵坐标上的点也最少也为2个
sort_y_point = sorted(y_point)
min_num = sort_y_point[0]
max_num = sort_y_point[-1]
if min_num < i < max_num: # 横坐标i因为是均值,因此需要在这个序列的最大最小值之间
for j in sort_y_point:
if j < i:
if 2 * i - j in sort_y_point: # 纵坐标对应的2个横坐标的均值恰好为i
count += 1
else: # 因为sort_y_point是升序的,一旦大于i,后面的就不可能了
break
return count
- 结果
点击获得更多编程练习题。欢迎Follow,感谢Star!!! 扫描关注微信公众号pythonfan,获取更多。