线段交

线段交

题目描述:
给定N个线段。求有交点的线段对数。
保证没有两条线段共线
输入:
一行一个整数N,表示线段的个数
第2~N+1行,每行四个实数,x1,y1,x2,y2,表示线段的两个端点(x1,y1)和(x2,y2)
输出:
一行一个整数,表示有交点的线段对数。
样例输入:
3
0.00 0.00 1.00 1.00
0.00 1.00 1.00 0.00
0.00 0.00 1.00 0.00
样例输出:
3
(先不说思路,先说坑,这俩坑卡了我两个小时,虽然两个低级错误,但确实容易忘,大佬不要见笑):
1.double类型不能用自带的max函数和min函数,比较要自定义函数;
2.double类型不能和0直接相比,应该和很接近0的一个数比,如0.0001。
下面是思路:
两条线段,我将第一条线段的两个端点定义为(x1,y1),(x2,y2);将第二条线段的两个端点定义为(x3,y3),(x4,y4)。
在第一条线段的两个端点都高(或低)于第二条线段,则其不可能有交点。

bool judge1(STU a,STU b)
{
if(maxx(a.x1,a.x2)<minn(b.x1,b.x2)||maxx(a.y1,a.y2)<minn(b.y1,b.y2)||minn(a.x1,a.x2)>maxx(b.x1,b.x2)||minn(a.y1,a.y2)>maxx(b.y1,b.y2))
{
return false;
}
else return true;
}

还有就是,
1.((x1-x3)(y4-y3)-(y1-y3)(x4-x3))((x2-x3)(y4-y3)-(y2-y3)(x4-x3))>0
2.((x3-x1)(y2-y1)-(y3-y1)(x2-x1))((x4-x1)(y2-y1)-(y4-y1)(x2-x1))>0
这两点只要满足一个,则无交点。

bool judge2(STU a,STU b)
{
if((1.0*(a.x1-b.x1)*(b.y2-b.y1)-1.0*(a.y1-b.y1)*(b.x2-b.x1))*(1.0*(a.x2-b.x1)*(b.y2-b.y1)-1.0*(a.y2-b.y1)*(b.x2-b.x1))>0.00001)
{
return false;
}
else if((1.0*(b.x1-a.x1)*(a.y2-a.y1)-1.0*(b.y1-a.y1)*(a.x2-a.x1))*(1.0*(b.x2-a.x1)*(a.y2-a.y1)-1.0*(b.y2-a.y1)*(a.x2-a.x1))>0.00001)
{
return false;
}
else return true;
}

以下为AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef struct//线段两端点
{
    double x1;
    double y1;
    double x2;
    double y2;
}STU;
double maxx(double a,double b)
{
    if(a>b) return a;
    else return b;
}
double minn(double a,double b)
{
    if(a>b) return b;
    else return a;
}
bool judge1(STU a,STU b)//第一判断条件
{
    if(maxx(a.x1,a.x2)<minn(b.x1,b.x2)||maxx(a.y1,a.y2)<minn(b.y1,b.y2)||minn(a.x1,a.x2)>maxx(b.x1,b.x2)||minn(a.y1,a.y2)>maxx(b.y1,b.y2))
    {
        return false;
    }
    else return true;
}
bool judge2(STU a,STU b)//第二判断条件
{
    if((1.0*(a.x1-b.x1)*(b.y2-b.y1)-1.0*(a.y1-b.y1)*(b.x2-b.x1))*(1.0*(a.x2-b.x1)*(b.y2-b.y1)-1.0*(a.y2-b.y1)*(b.x2-b.x1))>0.00001)
    {
        return false;
    }
    else if((1.0*(b.x1-a.x1)*(a.y2-a.y1)-1.0*(b.y1-a.y1)*(a.x2-a.x1))*(1.0*(b.x2-a.x1)*(a.y2-a.y1)-1.0*(b.y2-a.y1)*(a.x2-a.x1))>0.00001)
    {
        return false;
    }
    else return true;
}
bool xiangjiao(STU a,STU b)
{
    if(!judge1(a,b)) return false;
    else if(!judge2(a,b)) return false;
    else return true;
}
int main()
{
    int n,sum=0;
    cin>>n;
    STU stu[n+1];
    for(int i=1;i<=n;i++)
    {
        scanf("%lf%lf%lf%lf",&stu[i].x1,&stu[i].y1,&stu[i].x2,&stu[i].y2);
    }
    for(int i=1;i<n;i++)
    {
        for(int j=i+1;j<=n;j++)
        {
            if(xiangjiao(stu[i],stu[j])) sum++;
        }
    }
    printf("%d\n",sum);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值