题目:
http://poj.org/problem?id=3304题意:
有n个线段,给出线段两端点的坐标,求能否找到一条直线使得所有线段在这条直线上的映射存在公共点。思路:
存在公共点也就是在这个点的垂线经过所有的线段。
最多100条线段,直接枚举所有点对可能形成的直线,然后判断是否所有线段都经过这条直线,就是线段两个端点是否在直线两侧就行了。判断在两侧就是叉乘,注意判断枚举的点对是否是同一个点跳过就行了。
代码:
#define EPS 1e-8
#define N 112
int n,m,flag;
struct point
{
double x,y;
}a[N],b[N],c[N*2];
double cross3(point p0,point p1,point p2){
return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
int main()
{
int i,j,k,T,cas;
double x,y,z,xx,yy;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%lf%lf%lf%lf",&a[i].x,&a[i].y,&b[i].x,&b[i].y);
c[i]=a[i];c[i+n]=b[i];
}
flag=0;
for(i=0;!flag&&i<n*2;i++)
for(j=0;!flag&&j<i;j++)
{
m=1;
if(fabs(c[i].x-c[j].x)<EPS&&fabs(c[i].y-c[j].y)<EPS||fabs(c[i].x-c[j].y)<EPS&&fabs(c[i].y-c[j].x)<EPS)
continue;
for(k=0;k<n;k++)
{
x=cross3(c[i],c[j],a[k]);
y=cross3(c[i],c[j],b[k]);
if(x<0&&y<0||x>0&&y>0)m=0;
}
flag=m;
}
printf("%s\n",flag?"Yes!":"No!");
}
return 0;
}