您的位置:首页 > 其它

POJ 3304 判断线段相交(叉积)

2014-03-26 09:40 295 查看
题目链接http://poj.org/problem?id=3304

题解:同样是叉积的运用  此题需注意重点(坑啊~~~~(>_<)~~~~ )

#include<cstdio>
#include<cmath>
#include<cstring>
#define N 111
using namespace std;
int n;
struct Point
{
double x, y;
Point(double x = 0, double y = 0) : x(x), y(y) {}
};

struct segments
{
Point a, b;
}seg
;

typedef Point Vector; //Vector 为 Point的别名

const double eps = 1e-8;
int dcmp(double x)
{
if(fabs(x) < eps) return 0;
else return x < 0 ? -1 : 1;
}

//向量+向量=向量    点+向量=点
Vector operator + (Vector A, Vector B) {return Vector(A.x+B.x, A.y+B.y);}

//点-点=向量
Vector operator - (Point A, Point B) {return Vector(A.x-B.x, A.y-B.y);}

//向量*数=向量
Vector operator * (Vector A, double p) {return Vector(A.x*p, A.y*p);}

//向量/数=向量
Vector operator / (Vector A, double p) {return Vector(A.x/p, A.y/p);}

//点积:两者长度乘积再乘上夹角余弦 XaXb + YaYb
double Dot(Vector A, Vector B)
{
return A.x*B.x + A.y*B.y;
}

double Length(Vector A)
{
return sqrt(Dot(A, A));
}

//叉积:两向量v和w的叉积等于v和w组成的三角形的有向面积的两倍 XaYb - XbYa
double Cross(Vector A, Vector B)
{
return A.x*B.y - A.y*B.x;
}

int fun(Point a, Point b)
{

if(abs(a.x - b.x) < eps && abs(a.y - b.y) < eps) return 0;  //点
for(int i = 1; i <= n; i++)
if(Cross(a-seg[i].a, b - seg[i].a) * Cross(a-seg[i].b, b-seg[i].b) > eps)  //不相交大于0 相交小于0
return 0;
return 1;
}

int slove()
{
for(int i = 1; i <= n; i++)
for(int j = i+1; j <= n; j++)
{
if(fun(seg[i].a, seg[j].a))      return 1;
else if(fun(seg[i].a, seg[j].b)) return 1;
else if(fun(seg[i].b, seg[j].a)) return 1;
else if(fun(seg[i].b, seg[j].b)) return 1;
}

return 0;

}

int main ()
{
int T;
scanf("%d", &T);
while(T--)
{
scanf("%d", &n);
for(int i = 1; i <= n; i++)
scanf("%lf %lf %lf %lf", &seg[i].a.x, &seg[i].a.y, &seg[i].b.x, &seg[i].b.y);

if(n <= 2) {printf("Yes!\n"); continue;}

if(slove())
printf("Yes!\n");
else
printf("No!\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: