题目描述
本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
在平面直角坐标系中,两点可以确定一条直线。如果有多点在一条直线上, 那么这些点中任意两点确定的直线是同一条。
给定平面上 2 × 3 个整点{(x, y)|0 ≤ x < 2, 0 ≤ y < 3, x ∈ Z, y ∈ Z}(x,y)∣0≤x<2,0≤y<3,x∈Z,y∈Z,即横坐标 是 0 到 1(包含 0 和 1) 之间的整数、纵坐标是 0 到 2 (包含 0 和 2) 之间的整数 的点。这些点一共确定了 11 条不同的直线。
给定平面上 20×21 个整点 {(x, y)|0 ≤ x < 20, 0 ≤ y < 21, x ∈ Z, y ∈ Z}(x,y)∣0≤x<20,0≤y<21,x∈Z,y∈Z,即横 坐标是 0 到 19 (包含 0 和 19) 之间的整数、纵坐标是 0 到 20 (包含 0 和 20) 之 间的整数的点。
请问这些点一共确定了多少条不同的直线。
解题思路:
求解两不同点的直线表达式(最简),将系数存入集合,输出集合长度即可。
直线表达式有许多不同的形式:一般式 a*x+b*y+c = 0, 斜截式y = k*x +b
点斜式y-y0 = k(x - x0)等等。
本题中点的坐标均为整数,使用一般式的话前面的系数均为整数,相对来说更容易处理。
ps:斜截式我写了一点点,对k 和b 的没处理好,答案多出了许多......
求表达式的最简式,则需要找到其系数的最小公因式。
代码如下:
star = [(i, j) for i in range(20) for j in range(21)]
def gcd(m, n):
if n == 0:
return m
else:
return gcd(n, m % n)
ans = set()
for n, i in enumerate(star):
for j in star[n + 1:]:
a = i[1] - j[1]
b = j[0] - i[0]
c = i[0] * j[1] - j[0] * i[1]
gcdd = gcd(gcd(a, b), c)
step = (a / gcdd, b / gcdd, c / gcdd)
ans.add(step)
print(len(ans))
1.对于函数gcd(x,y),x与y的大小并不需要刻意处理(应该吧):
如 gcd(4,8)会return gcd(8, 4%8)<=>gcd(8,4)
gcd(0,5) 会return gcd(5,0) 等等。
2. 为避免重复,只会对本点( i ) 之后的点进行求解。
备注:
如果题目改变,则可直接在开头部分对star列表进行修改。