概述
蓝桥杯python组第2021届第二题
第二题 题目大意
在平面直角坐标系中,两点可以确定一条直线。如果有多点在一条直线上,那么这些中任意两点确定的直线是同一条。
给定平面上2X3个整点{(x,y)|0≤x<2,0≤y<3,x∈Z,y∈Z},横坐标是0到1(包含0和1)之间的整数、纵坐标是0到2(包含0和2)之间的整数的点。这些点一共确定了11条不同的直线。
给定平面上20X21个整点{(x,y)|0≤x<20,0≤y<21,x∈Z,y∈Z},横坐标是0到19(包含0和19)之间的整数、纵坐标是0到20(包含0和20)之间的整数的点。
请问这些点一共确定了多少条不同的直线。
总体思路
值得我们注意的一个点是我们需要确定的是不同的直线,而非不同的线段。因此会有相同的直线经过不同的多个点。这时我们考虑到为了表示这样的含义,我们利用斜率和截距的方式可以很好的进行表示:
y
=
k
x
+
b
;
k
=
(
y
2
−
y
1
)
/
(
x
2
−
x
1
)
y = kx + b; k = (y2-y1)/(x2-x1)
y=kx+b;k=(y2−y1)/(x2−x1)
思路一
我们通过确定不同的点之间确定的斜率与截距,将其放入集合中,利用集合的特征(唯一性)对重复的直线进行筛选。我们先将垂直于x轴的直线(斜率不存在的直线)排除在外,再统计其余的直线。
ptslist = [(x,y) for x in range(20) for y in range(21)]
# 确定点列表。平面上20X21个整点{(x,y)|0≤x<20,0≤y<21,x∈Z,y∈Z}
kdset = set() # 构建一个集合用于存储斜率和截距
# print(type(kdset))
for cor1 in ptslist:
for cor2 in ptslist:
# print(cor1,cor2)
if cor1[0] != cor2[0]: # 将斜率不存在的直线排除在外
k = (cor2[1]-cor1[1])/(cor2[0]-cor1[0])
d = cor2[1]-k*cor2[0]
kdset.add((round(k,10),round(d,10)))
#这里有一个小问题,如果我们不将其保留一定的小数位的话,我们所得到的结果与答案不符。
print(len(kdset)+20)
其中如果我们不将其保留一定的小数位的话,我们所得到的结果(47753)与答案(40257)不符。这个问题也希望各位能够帮忙解答一下,我个人理解可能是在系统内四舍五入时出现了差异。
思路二
我个人理解的话,虽然python是面向对象的语言,比赛中如果能够灵活地应用好,能够提高解题的理解和效率。但同时,如果能够使用简单的代码就可以解决问题,完全可以不用构建类。
class Line(object):
"""构建线对象"""
def __init__(self):
self.k = 0
self.b = 0
# 定义魔法方法,对其进行排序
def __lt__(self, t):
if self.k != t.k:
return self.k < t.k
return self.b < t.b
N = 300000
n = 0
# 构造列表l,其中每一个元素都是类里的一个特殊对象
l = [Line() for _ in range(N)]
for x1 in range(0, 20):
for y1 in range(0, 21):
for x2 in range(0, 20):
for y2 in range(0, 21):
if x1 != x2:
k = float((y2 - y1)) / (x2 - x1)
b = float(y2 - k * x2)
l[n].k = k
l[n].b = b
n += 1
L = l[0: n] # 进行切片处理,取出含有斜率和截距的列表
L.sort() # 进行排序
res = 1
for i in range(1, n): # 对斜率和截距不同的进行计数
if abs(L[i].k - L[i - 1].k) > 1e-8 or abs(L[i].b - L[i - 1].b) > 1e-8:
res += 1
print(res + 20)
最后
以上就是大胆玫瑰为你收集整理的蓝桥杯python组第2021届第二题蓝桥杯python组第2021届第二题的全部内容,希望文章能够帮你解决蓝桥杯python组第2021届第二题蓝桥杯python组第2021届第二题所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复