#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string.h>
#include <queue> //poj3304求是否存在一条直线可以与各个线段有交点(枚举,枚举线段的端点和其他全部线段的端点来判断是否满足与所有线段相交)
#define N 105
using namespace std;
const double eps=1e-8; //精度,相当于0
/*
若存在一条直线与所有线段相机相交,将该线旋转,平移,直到不能再动为止,此时该直线必定经过这些线段的某两个端点;
*/
struct segment
{
double x1, y1, x2, y2;
}p[N];
int n;
bool check(double x1, double y1, double x2, double y2)
{
int t;
double a1=x2-x1, b1=y2-y1, a2, b2, a3, b3;
if(sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1))<eps) //两个点的距离小于1e-8就等价于一点
return false;
for(t=0; t<n; ++t) //利用叉乘来判断直线和线段是否相交
{
a2=p[t].x1-x1;
b2=p[t].y1-y1;
a3=p[t].x2-x1;
b3=p[t].y2-y1;
if((a1*b2-b1*a2)*(a1*b3-b1*a3)>eps)break; //精度控制,eps这里相当于0
}
if(t<n)return false;
else return true;
}
int main()
{
int t, j, T, ans;
scanf("%d", &T);
while(T--)
{
scanf("%d", &n);
for(t=0; t<n; ++t)
{
scanf("%lf%lf%lf%lf", &p[t].x1, &p[t].y1, &p[t].x2, &p[t].y2);
}
if(n<3)
{
printf("Yes!\n");
continue;
}
ans=0;
for(j=0; j<n&&!ans; ++j) //只要存在一条直线满足条件就立刻输出
{
for(t=0; t<n&&!ans; ++t)
{
if(t==j)continue;
if(check(p[j].x1, p[j].y1, p[t].x2, p[t].y2)||check(p[j].x1, p[j].y1, p[t].x1, p[t].y1)||check(p[j].x2, p[j].y2, p[t].x1, p[t].y1)||check(p[j].x2, p[j].y2, p[t].x2, p[t].y2))
ans=1;
}
}
if(ans)
printf("Yes!\n");
else printf("No!\n");
}
return 0;
}
poj3304求是否存在一条直线可以与各个线段有交点
最新推荐文章于 2021-05-20 17:53:20 发布