Title Link
Title:
Give you a number of line segments, and find out whether they can project to a line, so that the projection of each line segment has at least one common intersection.
Explanation:
We make the perpendicular of that line through that common intersection. According to the nature of projection, it is not difficult to find that this line should have intersection with all line segments. Then it is converted to judge whether there is a straight line and all line segments have intersections. Now the question is how to find a straight line. If we think about it a little bit, we will find that it is useful that there are only two endpoints for each line segment. For all legal lines, the legal situation of the most boundary is that it passes through one endpoint of a certain line segment, so we enumerate the endpoint of the line segment, and judge whether it intersects with each line segment by using the line formed by the connection of two endpoint of the line segment. The method of judgment is to use cross product. The result of using cross product is positive and negative according to the position relation of two vectors. Select one of the two endpoints as the starting point of the vector, the other as the end point, and the two endpoints of all other segments as the end points for cross product respectively. If the cross product of the two endpoints is positive and negative, it means that the two endpoints of the segment are on both sides of the current line, that is to say, there are intersections. Of course, if the cross product is 0 coincidence, there are also intersections. That's how it's done.
Code:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cmath>
using namespace std;
int t,n,pd;
double eps=1e-8;
struct Point
{
double x,y;
};
int cmp(double x)
{
if(fabs(x)<eps)
return 0;
if(x>0)
return 1;
else
return -1;
}
bool operator != (Point x,Point y)
{
return (cmp(x.x-y.x)!=0||cmp(x.y-y.y)!=0);
}
struct Vector
{
double x,y;
};
struct Line
{
Point p,q;
}l[110];
double chaji(Vector x,Vector y)
{
return x.x*y.y-x.y*y.x;
}
int check(Point x,Point y)
{
Vector v1;
v1.x=x.x-y.x;
v1.y=x.y-y.y;
for(int i=1;i<=n;++i)
{
Point b=l[i].p,c=l[i].q;
Vector v2,v3;
v2.x=b.x-y.x;
v2.y=b.y-y.y;
v3.x=c.x-y.x;
v3.y=c.y-y.y;
int ji1,ji2;
ji1=cmp(chaji(v1,v2));
ji2=cmp(chaji(v1,v3));
if(ji1!=ji2||!ji1)
continue;
else
return 0;
}
return 1;
}
int main()
{
scanf("%d",&t);
while(t--)
{
pd=0;
scanf("%d",&n);
for(int i=1;i<=n;++i)
scanf("%lf%lf%lf%lf",&l[i].p.x,&l[i].p.y,&l[i].q.x,&l[i].q.y);
for(int i=1;i<=n;++i)
{
for(int j=i;j<=n;++j)
{
Point x,y;
x=l[i].p;
y=l[j].p;
if(x!=y)
{
if(check(x,y))
{
pd=1;
break;
}
}
x=l[i].p;
y=l[j].q;
if(x!=y)
{
if(check(x,y))
{
pd=1;
break;
}
}
x=l[i].q;
y=l[j].p;
if(x!=y)
{
if(check(x,y))
{
pd=1;
break;
}
}
x=l[i].q;
y=l[j].q;
if(x!=y)
{
if(check(x,y))
{
pd=1;
break;
}
}
}
}
if(pd==1)
printf("Yes!\n");
else
printf("No!\n");
}
return 0;
}