Hdoj1086
题意,给你n条线段然后让你判断有几个交点。
所以思路就是判断两条线段是否相交,然后for一下就好了啊
那么怎么判断两条线段相交呢
1. 好像普遍用叉积的方法吧【T^T】
叉积:矢量的矢量积
记作a×b,其模等于由a 和b作成的平行四边形的面积,方向与平行四边形所在平面垂直。
三角形ABC的面积=
【1】那么我们知道叉积是正数, a 在b 的顺时针方向;负数, b 在a 的顺时针方向; 0的话, 模相等且共线
(单纯补充)拉格朗日公式
a× (b×c) =b(a·c)-c(a·b),
那么根据【1】,我们就可以知道判定条件
cb×cd与cd×ca同号且bd×ba与ba×bc同号时是相交的,否则不香蕉…
2. 以前有一个学长说过一个idea,然后我也是一直这么做的…
这里只讲相交时的情况;不香蕉时满不满足只能自己感受了。
【1】先根据一条线段,计算另一条线段的点在该线段的【直线上】的点的纵坐标,然后和原来的点的纵坐标比较,if((y3>=w3&&y4<=w4)||(y3<=w3&&y4>=w4))
【2】再根据【另一条线段】,计算【另另线段】的点在【另一条线段】的【直线】上的点的纵坐标,然后比较,if((y2>=w2&&y1<=w1)||(y2<=w2&&y1>=w1))
【3】当然你还得判断一下两条线段斜率的不存在的时候
其中一条线段斜率不存在时,判断另一条线段(斜率存在)的两点是否在该线段的两端;if((x3>=x2&&x4<=x2)||(x4>=x2&&x3<=x2))
//很明显这样一个条件是不能判断相交的,但是接下来还是要去判断上面的【1】或者【2】
所以就可以证明了。
= =其实这样解释起来好烦
这道题看代码吧,代码可能好理解…但是我觉得我讲的也蛮清楚的T^T
【判断两条线段相交的一道题目】
Description
现在有两条线段在一个平面上,判断这两条线段是否相交(有一个公共点或有部分重合认为相交)。
Input
第一行输入一个整数T,表示输入的测试数量(1<=T<=1000),后面T组测试用例,每组占一行,每行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"。
Sample Input
2
1 2 2 1 0 0 2 2
-1 1 1 1 0 0 1 -1
Sample Output
Yes
No
代码如下
#include
#include
#include
#include
#include
using namespace std;
int main()
{
int n;
scanf("%d",&n);
while(n--)
{
double x1,x2,y1,y2,x3,x4,y3,y4,k1,k2;
double w1,w2,w3,w4;
int flag=0;
scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&x1,&y1,&x2,&y2,&x3,&y3,&x4,&y4);
if((x2-x1)==0) //如果斜率不存在
{
if((x3>=x2&&x4<=x2)||(x4>=x2&&x3<=x2))
flag+=1;
}
else //如果存在
{
k1=(double)(y2-y1)/(x2-x1);
w3=k1*(x3-x2)+y2;
w4=k1*(x4-x2)+y2;
if((y3>=w3&&y4<=w4)||(y3<=w3&&y4>=w4)) //看图模拟
flag+=1;
}
if((x4-x3)==0) //继续判断斜率是否存在
{
if((x2>=x3&&x1<=x3)||(x1>=x3&&x2<=x3))
flag+=1;
}
else
{
k2=(double)(y4-y3)/(x4-x3);
w1=k2*(x1-x3)+y3;
w2=k2*(x2-x3)+y3;
if((y2>=w2&&y1<=w1)||(y2<=w2&&y1>=w1))
flag+=1;
}
if(flag==2)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long LL;
typedef pair PII;
using namespace std;
bool Judge(double x1,double y1,double x2,double y2,double x3,double y3,double x4,double y4)
{
double k1,w3,w4;
int flag=0;
if((x2-x1)==0) //如果斜率不存在
{
if((x3>=x2&&x4<=x2)||(x4>=x2&&x3<=x2))
flag+=1;
}
else //如果存在
{
k1=(double)(y2-y1)/(x2-x1);
w3=k1*(x3-x2)+y2;
w4=k1*(x4-x2)+y2;
if((y3>=w3&&y4<=w4)||(y3<=w3&&y4>=w4)) //看图模拟
flag+=1;
}
if(flag) return true;
return false;
}
int main()
{
double x[205];
double y[205];
double po[105][4];
int T,n;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
int n1,n2;
n1=n2=0;
for(int i=0;i