线段交
题目描述:
给定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;
}