题目
思路
投影就是把线段两个端点向直线做垂线,两个垂足连起来的线段。
显然只要枚举直线的垂线,然后判断是否经过所有线段就行。
代码
#include<iostream>
#include<cstdio>
using namespace std;
int T,n,w1,w2,w3,w4,js;
struct node
{
double x,y;
}p1[1000010],p2[1000010];
bool klsy(double x,double y,double xx,double yy,double xx1,double yy1,double xx2,double yy2)
{
if(((xx-x)*(yy1-y)-(xx1-x)*(yy-y))*((xx-x)*(yy2-y)-(xx2-x)*(yy-y))<=0)
return 1;
return 0;
}
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=1; i<=n; i++)
scanf("%lf%lf%lf%lf",&p1[i].x,&p1[i].y,&p2[i].x,&p2[i].y);
js=0;
for(register int i=1; i<=n; i++)
{
if(js==1)
break;
for(register int j=1; j<=n; j++)
{
w1=0,w2=0;
w4=0,w3=0;
if(p1[i].x==p2[j].x&&p1[i].y==p2[j].y)
w1=1;
else
{
for(register int k=1; k<=n; k++)
if(!klsy(p1[i].x,p1[i].y,p2[j].x,p2[j].y,p1[k].x,p1[k].y,p2[k].x,p2[k].y))
{
w1=1;
break;
}
}
if(p1[i].x==p1[j].x&&p1[i].y==p1[j].y)
w2=1;
else
{
for(register int k=1; k<=n; k++)
if(!klsy(p1[i].x,p1[i].y,p1[j].x,p1[j].y,p1[k].x,p1[k].y,p2[k].x,p2[k].y))
{
w2=1;
break;
}
}
if(p2[i].x==p2[j].x&&p2[i].y==p2[j].y)
w3=1;
else
{
for(register int k=1; k<=n; k++)
if(!klsy(p2[i].x,p2[i].y,p2[j].x,p2[j].y,p1[k].x,p1[k].y,p2[k].x,p2[k].y))
{
w3=1;
break;
}
}
if(p2[i].x==p1[j].x&&p2[i].y==p1[j].y)
w4=1;
else
{
for(register int k=1; k<=n; k++)
if(!klsy(p2[i].x,p2[i].y,p1[j].x,p1[j].y,p1[k].x,p1[k].y,p2[k].x,p2[k].y))
{
w4=1;
break;
}
}
if(w1==0||w2==0||w3==0||w4==0)
{
printf("Yes!\n");
js=1;
break;
}
}
}
if(js==0)
printf("No!\n");
}
return 0;
}