POJ 3304 Segment 直线与线段相交 + 枚举
2013-08-29 10:34
281 查看
若存在这样一条直线,过投影相交区域作直线的垂线,该垂线必定与每条线段相交,问题转化为问是否存在一条线和所有线段相交;
若存在一条直线与所有线段相机相交,将该线旋转,平移,直到不能再动为止,此时该直线必定经过这些线段的某两个端点;
所以枚举任意两个端点即可。
需要注意的是,当枚举的两个端点很近的时候,即sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))<eps时,那么这两个点是可以认为重合的,由于如果把这两点的连线作为向量,向量的模会很小,就可能导致无论怎么做叉积结果都为0从而认为各个点都是和这两个点共线的。因此,在枚举两个端点的时候要避免这种情况,同时,避免枚举这种情况之后也一定不会丢解。
View Code
若存在一条直线与所有线段相机相交,将该线旋转,平移,直到不能再动为止,此时该直线必定经过这些线段的某两个端点;
所以枚举任意两个端点即可。
需要注意的是,当枚举的两个端点很近的时候,即sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))<eps时,那么这两个点是可以认为重合的,由于如果把这两点的连线作为向量,向量的模会很小,就可能导致无论怎么做叉积结果都为0从而认为各个点都是和这两个点共线的。因此,在枚举两个端点的时候要避免这种情况,同时,避免枚举这种情况之后也一定不会丢解。
View Code
#include<stdio.h> #include<string.h> #include<math.h> #define eps 10e-8 struct point { double x, y; }; struct segment { point s, t; }; segment s[101]; int n; double ff(double x)//平方 { return x*x; } bool dis(point a, point b)//判断2个点是不是同一个点,本题很近的点就算是同一个点 { double ret = sqrt(ff(a.x - b.x )+ff(a.y - b.y)); if(-eps < ret && ret < eps)return 0; return 1; } double cross(point o, point a, point b)//叉积 { return (a.x - o.x)*(b.y - o.y)- (a.y - o.y)*(b.x - o.x); } bool judge(point a, point b)//直线的2个点位a,b,判断这条直线与n条线段是否相交,都相交返回1,否则返回0. { if(!dis(a, b))return 0; int i; for(i=1;i<=n;i++) if(cross(a, b, s[i].s)*cross(a, b, s[i].t) > eps)return 0; return 1; } int main() { int cas,i ,j ; scanf("%d",&cas); while(cas--) { scanf("%d",&n); for(i=1;i<=n;i++) scanf("%lf%lf%lf%lf", &s[i].s.x, &s[i].s.y, &s[i].t.x, &s[i].t.y); bool ok = 0; if(n==1)ok = 1; for(i=1;i<n;i++)//枚举线段的端点 for(j=i+1;j<=n;j++) if(judge(s[i].s, s[j].s)||judge(s[i].s, s[j].t)||judge(s[i].t, s[j].s)||judge(s[i].t, s[j].t)){ok=1;break;} puts(ok ? "Yes!":"No!"); } return 0; }
相关文章推荐
- POJ 3304 Segment 直线与线段相交 + 枚举
- POJ 3304(计算几何初步——判断线段和直线相交,加上枚举)
- POJ 3304 Segment 直线与线段相交
- POJ 3304 Segment 直线与线段相交
- POJ 3304 Segments [判断线段和直线相交]
- poj 3304 Segments--直线和线段相交
- Poj 3304 Segments 【线段于直线相交】
- poj 3304 Segments(利用叉积求是否存在直线与所给线段相交)
- POJ 3304 Segments[直线与线段相交]
- poj 3304 判断是否有与所有线段相交的直线
- POJ3304 Segments 【线段直线相交】
- POJ 3304 Segments(直线与线段相交判定)
- POJ 3304 Segments (直线和线段相交判断)
- poj 3304 Segments(判断直线与线段相交)
- poj 3304 Segments (题意理解出错,错误的只枚举了过线段的直线)
- POJ 3304 判断线段和直线相交
- POJ 3304 segments (直线与线段相交)
- POJ 3304 Segments(判断线段和直线是否相交)
- POJ 3304 Segments <计算几何(直线与线段相交判断)>
- poj 3304Segments(直线与线段的相交关系)