直线 问题

蓝桥杯 | 直线 问题 | python

题目描述
本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
在平面直角坐标系中,两点可以确定一条直线。如果有多点在一条直线上, 那么这些点中任意两点确定的直线是同一条。
给定平面上 2 × 3 个整点 (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,即横坐标是 0 到 19 (包含 0 和 19) 之间的整数、纵坐标是 0 到 20 (包含 0 和 20​) 之间的整数的点。
请问这些点一共确定了多少条不同的直线。
运行限制
最大运行时间:1s
最大运行内存: 128M

2 × 3 个整点:
在这里插入图片描述

  1. 方案一
    在这里插入图片描述
import os
import sys

class Line(object):                 # 直线类
    # 用起点和终点坐标表示直线有重复不方便,还可以记录直线的斜率和截距
    def __init__(self):             # 初始化函数
        self.k = 0                  # 斜率
        self.b = 0                  # 截距

    def __lt__(self, t):            # L.sort()调用
        if self.k != t.k:           # 如果斜率不同,斜率小的排前面
            return self.k < t.k
        return self.b < t.b         # 如果斜率相同,截距小的排前面
        
N = 200000                          # 取大数,后面切片
l = [Line() for _ in range(N)]      # 列表每个元素都是一个直线对象
n = 0                               # 索引
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:        # x坐标不相同,k存在
                    k = float((y2 - y1)) / (x2 - x1)    # 斜率
                    b = float(y2 - k * x2)              # 截距
                    l[n].k = k      # 开始n=0,赋值索引=0(第一个)直线对象
                    l[n].b = b
                    n += 1          # 赋值下一个索引的直线对象
# 四层循环完,除了垂直的直线,都存到l里,一共存了n个直线对象
L = l[0: n]                         # 切片存入L
# 对所有直线去重
L.sort()                            # 排序(方便去重),调用__lt__比较直线大小                   
res = 1                             # 索引=0的直线先找到一条
for i in range(1, n):               # 索引=1到n-1
    # 比较浮点型的不同
    if abs(L[i].k - L[i - 1].k) > 1e-8 or abs(L[i].b - L[i - 1].b) > 1e-8:      # 斜率不同 or 截距不同
        res += 1                    # 相同直线过滤掉,不同直线累加1
print(res + 20)                     # 加上x坐标相同,k不存在的垂直直线(0到19共20条)
  1. 方案二
'''
方案一利用排序去重耗费时间太长,方案二利用集合结构去重不超过时间限制
'''
import os
import sys

# 请在此输入您的代码
xList=[i for i in range(20)]
yList=[i for i in range(21)]
points=[(x,y) for x in xList for y in yList]    # 所有整数点,元组类型
# print(points)
s=set()                                         # 利用集合结构去重

def getLine(p,q):                               # 集合中任意两点p(x1,y1),q(x2,y2)
    k=(q[1]-p[1])/(q[0]-p[0])                   # 斜率
    b=q[1]-q[0]*k                               # 截距
    return round(k,8),round(b,8)                # 返回元组(斜率,截距)

for p in points:
    for q in points:                            # 遍历集合中所有起点和终点
        if p!=q and p[0]!=q[0]:                 # 两点不同且x坐标不同,排除垂直直线
            s.add(getLine(p,q))                 # 得到一个元组就加入集合里,自动去重
print(len(s)+20)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值