1264 线段相交

基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题
 收藏
 关注
给出平面上两条线段的两个端点,判断这两条线段是否相交(有一个公共点或有部分重合认为相交)。 如果相交,输出"Yes",否则输出"No"。
Input
第1行:一个数T,表示输入的测试数量(1 <= T <= 1000)
第2 - T + 1行:每行8个数,x1,y1,x2,y2,x3,y3,x4,y4。(-10^8 <= xi, yi <= 10^8)
(直线1的两个端点为x1,y1 | x2, y2,直线2的两个端点为x3,y3 | x4, y4)
Output
输出共T行,如果相交输出"Yes",否则输出"No"。
Input示例
2
1 2 2 1 0 0 2 2
-1 1 1 1 0 0 1 -1
Output示例
Yes
No


#include<stdio.h>

#include<algorithm>

using namespace std;
int t;
struct point{
double x;
double y;
};
point a,b,c,d,ab,cd;


int judge()//判断是否重合
{
if(ab.x==0&&(a.x==c.x||a.x==d.x||b.x==c.x||b.x==d.x))
return 1;//斜率不存在时的重合

double k=cd.y/cd.x;
double b=c.y-cd.y*c.x/cd.x;
if(a.y==k*a.x+b)
return 1;
return 0;
}
int check()
{

double k1,k2,b1,b2;
double maxx,minx,maxy,miny;
ab={(b.x-a.x),(b.y-a.y)};

cd={(d.x-c.x),(d.y-c.y)};


//平行 
if(ab.x*cd.y-ab.y*cd.x==0)
{
if(judge())//判断是否重合
return 1;
else
return 0;
}


//斜率不存在 
if(ab.x==0) 
{
k2=cd.y/cd.x;
b2=c.y-cd.y*c.x/cd.x;
maxy=max(a.y,b.y);
miny=min(a.y,b.y);
if(k2*a.x+b2>=miny&&k2*a.x+b2<=maxy)
return 1;
else
return 0;

else if(cd.x==0)
{
k1=ab.y/ab.x;
b1=a.y-ab.y*a.x/ab.x;
maxy=max(c.y,d.y);
miny=min(c.y,d.y);
if(k1*c.x+b1>=miny&&k1*c.x+b1<=maxy)
return 1;
else
return 0;
}
else if(ab.x!=0&&cd.x!=0)
{
// puts("debug");
k2=cd.y/cd.x;
b2=c.y-cd.y*c.x/cd.x;
k1=ab.y/ab.x;
b1=a.y-ab.y*a.x/ab.x;
// printf("%lf %lf %lf %lf\n",k1,b1,k2,b2);
if(k1==k2&&b1==b2)
return 1;
double xx=(b2-b1)/(k1-k2);
double min1,min2,max1,max2;
min1=min(a.x,b.x);
max1=max(a.x,b.x);
min2=min(c.x,d.x);
max2=max(c.x,d.x);
minx=max(min1,min2);
maxx=min(max1,max2);

//printf("%lf %lf\n",minx,maxx);
if(xx>=minx&&xx<=maxx)
return 1;
else
return 0;
}
else
return 1;
}


int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%lf %lf %lf %lf %lf %lf %lf %lf",&a.x,&a.y,&b.x,&b.y,&c.x,&c.y,&d.x,&d.y);
if(check()==1)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}


阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页