判断直线和线段是否相交的题目。
题意是给你n条线段,判断是否存在一条直线,使所有线段到这条直线的投影至少有一个交点。
你可以假设存在一条这样的直线,所有线段在这条直线上的投影组成一片区域,至少有另一条直线可以垂直这片区域(有可能是个点),如果不存在另一条直线也就不存在假设存在的那样一条直线。这就是原命题与逆否命题的转换吧。
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<time.h>
#include<math.h>
using namespace std;
const int maxn =210;
const double eps = 1e-8;
int sig(double d)
{
return fabs(d)<1e-8?0:d<0?-1:1;
}
int T,n;
struct point
{
double x,y;
point(double x=0,double y=0):x(x),y(y) {}
} s[maxn];
double xmult(point p1,point p2,point p0)
{
return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
int segLineCross(point a,point b,point c,point d)
{
int d1,d2;
d1=sig(xmult(a,b,c));
d2=sig(xmult(a,b,d));
if((d1^d2)==-2)
return 1;
if(d1==0||d2==0)return 2;
return 0;
}
int judge(point a,point b)
{
if(sig(a.x-b.x)==0 && sig(a.y-b.y)==0)return 0;
for(int i=0; i<2*n-1; i+=2)
{
if(segLineCross(a,b,s[i],s[i+1])==0)
return 0;
}
return 1;
}
void solve()
{
for(int i=0; i<2*n-1; i++)
for(int j=i+1; j<=2*n-1; j++)
{
if(judge(s[i],s[j])==1)
{
printf("Yes!\n");
return ;
}
}
printf("No!\n");
return ;
}
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=0; i<2*n; i++)
{
scanf("%lf%lf",&s[i].x,&s[i].y);
}
solve();
}
return 0;
}