IzackI 发表于 2022-10-14 18:47:29

2021蓝桥杯软件类省赛试题B

本帖最后由 IzackI 于 2022-10-14 18:54 编辑

题目:在平面直角坐标系中,两点可以确定一条直线。如果有多点在一条直线上,那么这些点中任意两点确定的直线是同一条。
给定平面上2×3个整点{(x,y)0 ≤x<2,0≤y<3,x ∈Z,y EZ),即横坐标是0到1(包含0和1)之间的整数、纵坐标是0到2(包含0和2)之间的整数的点。这些点一共确定了11条不同的直线。
给定平面上20×21个整点{(x,y)|0 ≤x<20,0≤y< 21,x EZ,y ∈Z),即横坐标是0到19(包含0和19)之间的整数、纵坐标是0到20(包含0和20)之间的整数的点。请问这些点一共确定了多少条不同的直线。

鱼u们,题目答案貌似是40257,可是我跑出来是47753,哪里错了啊{:10_266:}
#首先建立20*21整点的集合

list1 = []
for i in range(0,20):
    for each in range(0,21):
      list1.append((i,each))
del i
del each

#以上确定点集合

#下面将所有点两两形成直线穷举
#两点坐标可以确定斜率,基于简单原则,使用斜截式
#考虑斜率不存在的情况
list2 = list1
aggregation = set({})
for i in list1:
    for each in list2:
      if i == each:#同一点无法构成直线,排除
            continue
      elif i == each:#斜率不存在的直线单独讨论
            a = (i,"*")
            aggregation.add(a)
            continue
      
      else:#计算斜率存在的直线斜截式的k,b。存入集合,以备统计
            y1 = i
            y2 = each
            x1 = i
            x2 = each

            k = (y1 - y2) / (x1 - x2)
            b = y2 - k*x2
            a = (k,b)
            aggregation.add(a)

#程序主体基本完成


            
print(len(aggregation))

lymww 发表于 2022-10-15 01:41:40

第34行代码   a = (k,b)   改为 a = (round(k,3), round(b,3))   运行结果就对了,且保留的尾数必须大于等于3才行

至于为什么这样,我也不是清楚{:7_138:}

whx_py 发表于 2022-10-15 13:08:44

我的理解是:很多时候,k = (y1 - y2) / (x1 - x2)结果很有可能是无限循环小数并且不以分数形式呈现,而 b = y2 - k*x2 = y2 - (y1 - y2) / (x1 - x2) *x2 的结果也就是个小数了。即使是我们知道的4个点在同一条y=kx+b上时,取不同的(x1,x2,y1,y2)可能会造成在求b时在小数点后几位上有点不同,但事实上值是相同的,或者说四舍五入以后结果一样。就好比a=1/3=0.3 3循环,a*3=0.9 9循环,表面上和1、和1.000......00001 (无数个0)不同,但结果都是1。

IzackI 发表于 2022-10-15 18:41:55

lymww 发表于 2022-10-15 01:41
第34行代码   a = (k,b)   改为 a = (round(k,3), round(b,3))   运行结果就对了,且保留的尾数必须大于等 ...

三楼的回复我认为有些道理
我自己也思考了挺长时间,结合了你的回复,感觉可能精度的问题

IzackI 发表于 2022-10-15 18:42:56

whx_py 发表于 2022-10-15 13:08
我的理解是:很多时候,k = (y1 - y2) / (x1 - x2)结果很有可能是无限循环小数并且不以分数形式呈现,而 b...

我也觉得可能是这样,谢谢
页: [1]
查看完整版本: 2021蓝桥杯软件类省赛试题B