思路见此处
根据链接的代码,我改写成更易于自己理解的代码
n = int(input())
coordinates = [input()for _ in range(n)]
def count_squares(coordinates):
count = 0
coordinates_set = set(tuple(map(int,coord.split()))for coord in coordinates)
for i in range(len(coordinates)):
x1,y1 = map(int,coordinates[i].split())
for j in range(i+1,len(coordinates)):
x2,y2 = map(int,coordinates[j].split())
dx = x2 - x1
dy = y2 - y1
p3 = (x1+dy,y1-dx)
p4 = (x2+dy,y2-dx)
if p3 in coordinates_set and p4 in coordinates_set:
count += 1
p5 = (x1-dy,y1+dx)
p6 = (x2-dy,y2+dx)
if p5 in coordinates_set and p6 in coordinates_set:
count += 1
return count // 4
这段代码的目的是计算在给定的坐标点集合中可以构成的正方形的数量。让我们一步步分析代码的结构和功能。
代码分析
n = int(input())
coordinates = [input() for _ in range(n)]
- 接收输入:
- 首先,程序读取一个整数
n
,表示将要输入的坐标的数量。 - 然后,通过列表推导式循环
n
次,读取每一行输入作为坐标,存储在coordinates
列表中。
- 首先,程序读取一个整数
def count_squares(coordinates):
count = 0
coordinates_set = set(tuple(map(int, coord.split())) for coord in coordinates)
- 定义函数
count_squares
:count
变量用于计数,初始化为 0。- 使用集合
coordinates_set
来存储所有坐标点的元组形式,确保方便快速查找,并自动去除重复坐标。map(int, coord.split())
将字符串坐标分割并转为整数。
for i in range(len(coordinates)):
x1, y1 = map(int, coordinates[i].split())
for j in range(i + 1, len(coordinates)):
x2, y2 = map(int, coordinates[j].split())
- 双重循环遍历所有坐标对:
- 第一个循环
i
遍历所有输入的坐标 (第一个点P1
),第二个循环j
遍历后面的坐标 (第二个点P2
)。 x1, y1 = map(int, coordinates[i].split())
和x2, y2 = map(int, coordinates[j].split())
解析出当前坐标点的 x 和 y 值。
- 第一个循环
dx = x2 - x1
dy = y2 - y1
p3 = (x1 + dy, y1 - dx)
p4 = (x2 + dy, y2 - dx)
if p3 in coordinates_set and p4 in coordinates_set:
count += 1
- 计算正方形的潜在顶点:
- 计算从
P1
到P2
的向量(dx, dy)
。 - 通过将向量旋转 90 度,得到新点
p3
和p4
,这两个点是形成正方形的候选点。 - 检查
p3
和p4
是否都在coordinates_set
中。如果是,说明找到了一个正方形,计数器count
加 1。
- 计算从
p5 = (x1 - dy, y1 + dx)
p6 = (x2 - dy, y2 + dx)
if p5 in coordinates_set and p6 in coordinates_set:
count += 1
- 检查另一种方向的正方形:
- 计算另一个旋转方向得到的新点
p5
和p6
。同样检查这两个点是否在集合中,如果是,计数器count
又加 1。
- 计算另一个旋转方向得到的新点
return count // 4
- 返回计算结果:
- 最后,由于每个正方形被计算了 4 次,返回
count // 4
得到实际的正方形数量。
- 最后,由于每个正方形被计算了 4 次,返回
总结
- 程序通过输入坐标,使用双重循环遍历所有可能的点对并基于向量旋转的方法来检测是否能形成正方形,最后返回正方形的总数。这种方法使用集合来提高查找效率,确保算法的性能。