蓝桥杯 2021b组 直线

题目

题目描述:
在平面直角坐标系中,两点可以确定一条直线。
如果有多点在一条直线上,那么这些点中任意两点确定的直线是同一条。
给定平面上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) 之间的整数的点。
请问这些点一共确定了多少条不同的直线。

解题思路

主体

  • 建立坐标系
  • 考虑每条直线的斜率和截距

筛选

  • 先把每条直线的斜率和截距记录下来,在进行判重,因为截距是浮点数,所以判重需要注意

方法

  • 排序,按照斜率优先,斜率相等排截距
  • 排完后比较前后两个元素,如果元素斜率不等,就加一条直线,如果斜率相等后截距不等,也加一条直线
  • 不能用0判断,因为是浮点数,可能不等于0,考虑极值1e-8进行比较差值绝对值
#include<bits/stdc++.h>
using namespace std;
struct  zhixian  //记录 
{
    double k;
    double b;
}a[500000];
bool cmp(zhixian q,zhixian w)  //排序 
{
    if(q.k!=w.k)
    return q.k>w.k;
    else
    return q.b>w.b;
} 
int main(){
    int temp=0;
    for(int x1=0;x1<20;x1++)  //遍历每个点 
    for(int y1=0;y1<21;y1++)
    for(int x2=0;x2<20;x2++)
    for(int y2=0;y2<21;y2++)
    {
        if(x1!=x2)  //分母不为零,垂直另算 
    {
        double k=(double)(y2-y1)/(x2-x1);
        double b=(double)(y2-x2*k);
        //a[temp].k=k;
        //a[temp++].b=b;
        a[temp++]={k,b} ;
    }
    }
    int ans=0;
    sort(a,a+temp,cmp);
    for(int i=0;i<temp;i++)
    if(fabs(a[i].k-a[i+1].k)>1e-8||fabs(a[i].b-a[i+1].b)>1e-8)
    ans++; 
    ans+=20;  //垂直的有20条 
    cout<<ans<<endl;
    return 0;
}

不懂私信或评论

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值