Codility每周一课:P92.4 DiamondsCount

版权声明:AnFany https://blog.csdn.net/qq_32882309/article/details/88715122

0.png

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,因为可以找到两个菱形,如下图所示:

image

给定数组:X=[1,2,3,3,2,1],Y=[1,1,2,2,2],函数应该返回0,因为不能构成满足条件的菱形:

image

假定:

  1. N是区间[4,1500]内的整数;
  2. 数组X,Y的每个元素都是区间[0,N−1]内的整数;
  3. 给定的N个点都是两两不同的。
  • 解题思路

因为菱形的对角线需要和坐标轴平行,因此组成菱形的四个点需要满足下面的条件:

  1. 上下2个点的横坐标是一样的;
  2. 左右2个点的纵坐标是一样的;
  3. 上下2个点的纵坐标和的均值恰好是左右2个点的纵坐标;
  4. 左右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
  • 结果

image

点击获得更多编程练习题。欢迎Follow,感谢Star!!! 扫描关注微信公众号pythonfan,获取更多。

image

image

猜你喜欢

转载自blog.csdn.net/qq_32882309/article/details/88715122