基准时间限制: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
李陶冶 (题目提供者)
题解:这道题就是用差积来判断线段 是否相交
比如线段AB CD
ABxBC>0表示C在AB的顺时针方向ABxBD>0说明D也在顺时针方向 这两个差积同号表示C D在线段AB 同侧
在判断A B在CD哪侧就可以判断是否相交
简而言之 可以先想想直线与线段相交的条件
另 也可以先用快速排斥再判断至少一次跨立判断就也OK
每天进步一点点
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
using namespace std;
const double p=1e-10;
struct node
{
double x,y;
}a,b,c,d;
int jisuan(node a,node b,node c,node d)
{
double p1,p2,p3,p4;
p1=(d.x-c.x)*(d.y-a.y)-(d.y-c.y)*(d.x-a.x);//DCxDA
p2=(d.x-c.x)*(d.y-b.y)-(d.y-c.y)*(d.x-b.x);//DCxDB
p3=(b.x-a.x)*(b.y-d.y)-(b.y-a.y)*(b.x-d.x);//BAxBD
p4=(b.x-a.x)*(b.y-c.y)-(b.y-a.y)*(b.x-c.x);//BAxBC
if(p1*p2<=p&&p3*p4<=p)//double判断有精度问题 注意
return 1;
return 0;
}
void duandian()
{
scanf("%lf%lf",&a.x,&a.y);
scanf("%lf%lf",&b.x,&b.y);
scanf("%lf%lf",&c.x,&c.y);
scanf("%lf%lf",&d.x,&d.y);
if(jisuan(a,b,c,d))
cout<<"yes"<<endl;
else
cout<<"no"<<endl;
}
int main()
{
int T;
cin>>T;
while(T--)
{
duandian();
}
return 0;
}