poj 3304 Segments-直线跟线段相交
poj 3304 Segments--直线和线段相交
/* 题意:给一些线段 问你是否存在这样一条直线:所有这些线段在直线上的投影有公共点 假设存在 那么过这个点,做这条直线的垂线,这条垂线过所有线段 因为所有线段的投影都覆盖这点,因为他们的投影有这个公共点么 所以就是找一条直线穿过所有线段 所以枚举任意两个点组成的直线 看是否满足要求 */ #include<stdio.h> #include<math.h> const double zero=1e-8; struct point { double x,y; }; struct segment//线段 { point p1,p2; }s[110]; point pp[210];//村所有的点 int t,n; int equal(point p1,point p2)//判断是否是同一个点 { if(fabs(p1.x-p2.x)<=zero&&fabs(p1.y-p2.y)<=zero) return 1; return 0; } double cross(point p,point v1,point v2)//做叉积 { return (v2.x-v1.x)*(p.y-v1.y)-(p.x-v1.x)*(v2.y-v1.y); } int sCrossL(point s1,point s2,point l1,point l2)//判断直线是否穿过线段 { if(cross(s1,l1,l2)*cross(s2,l1,l2)<=0) return 1; return 0; } int main() { int i,j,k; scanf("%d",&t); while(t--) { scanf("%d",&n); for(i=0;i<n;++i) { scanf("%lf%lf%lf%lf",&s[i].p1.x,&s[i].p1.y,&s[i].p2.x,&s[i].p2.y); pp[i*2+0].x=s[i].p1.x; pp[i*2+0].y=s[i].p1.y; pp[i*2+1].x=s[i].p2.x; pp[i*2+1].y=s[i].p2.y; } for(i=0;i<2*n-1;i++) { for(j=i+1;j<2*n;++j)//枚举点 { if(!equal(pp[i],pp[j]))//不是同一个点 { for(k=0;k<n;k++)//测试所有的边 if(!sCrossL(s[k].p1,s[k].p2,pp[i],pp[j])) break; if(k==n) break; } } if(k==n) break; } if(k==n) printf("Yes!\n"); else printf("No!\n"); } return 0; }