http://poj.org/problem?id=3304
求多条的线段的投影是否有公共部分
如果存在一条直线与所有线段相交,则所有的线段的投影有公共部分
枚举所有的端点,即枚举直线 然后枚举所有线段看是否存在所有相交的情况
若存在,则直接跳出,否则接着枚举直线
要注意的是,题目要求如果俩个点之间的距离小于10-8,则认为两个点是同一个点
#include<stdio.h>
#include<math.h>
#include<string.h>
#define M 110
#define eps 1e-8
struct point
{
double x,y;
}po[M*2];
struct lineseg
{
point a,b;
}line[M];
double Getlen(point a,point b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double multi(point a,point b,lineseg L)
{
double x1=a.x-b.x;
double y1=a.y-b.y;
double x2=a.x-L.a.x;
double y2=a.y-L.a.y;
double x3=a.x-L.b.x;
double y3=a.y-L.b.y;
return ((x1*y2-x2*y1)*(x1*y3-y1*x3));
}
bool Judge(lineseg L,point a,point b)//判断直线ab和线段L是否相交
{
if(multi(a,b,L)<=eps)//判断线段L的两个端点是否在直线的两边
return true;
return false;
}
int main()
{
int cas;
int n;
int i,j,k;
scanf("%d",&cas);
while(cas--)
{
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%lf%lf%lf%lf",&po[i*2].x,&po[i*2].y,&po[i*2+1].x,&po[i*2+1].y);
line[i].a=po[i*2];
line[i].b=po[i*2+1];
}
if(n==1||n==2)
{
printf("Yes!\n");
continue;
}
bool flag=false;
for(i=0;i<n*2;i++)
{
for(j=i+1;j<n*2;j++)//枚举两个点
{
if(Getlen(po[i],po[j])<=eps)//若两点间距离小于1e-8,认为这两点是同一个点
continue;
for(k=0;k<n;k++)//枚举线段
if(!Judge(line[k],po[i],po[j]))
break;
if(k==n) flag=true;
if(flag) break;
}
if(flag) break;
}
if(flag)
printf("Yes!\n");
else printf("No!\n");
}
return 0;
}