题目描述:
题解:
计算几何,坑点极多。
首先很明显存在一条直线穿过所有线段即$Yes$。
考虑枚举任意两个端点。
注意同一条线段上的也要枚举!
注意$eps=1e-8$!
注意两点重合就不用判了!
代码:
#include#include #include #include using namespace std;const int N = 150;const double eps = 1e-8;struct Point{ double x,y; Point(){} Point(double x,double y):x(x),y(y){} Point operator - (const Point&a)const{ return Point(x-a.x,y-a.y);} double operator ^ (const Point&a)const{ return x*a.y-y*a.x;}};typedef Point Vector;struct Line{ Point p; Vector v; Line(){} Line(Point p,Vector v):p(p),v(v){}};int n;Point s[N][2];int dcmp(double x){ if(fabs(x) 0?1:-1;}bool diff(Line l,Point a,Point b){ return dcmp(l.v^(a-l.p))*dcmp(l.v^(b-l.p))<=0;}int check(Point a,Point b){ if(!dcmp(a.x-b.x)&&!dcmp(a.y-b.y))return 0; Line l = Line(a,b-a); for(int i=1;i<=n;i++) if(!diff(l,s[i][0],s[i][1]))return 0; return 1;}void work(){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%lf%lf%lf%lf",&s[i][0].x,&s[i][0].y,&s[i][1].x,&s[i][1].y); int FG = 0; for(int i=1;!FG&&i<=n;i++)for(int j=i;!FG&&j<=n;j++) if(check(s[i][0],s[j][0])||check(s[i][0],s[j][1])||check(s[i][1],s[j][0])||check(s[i][1],s[j][1]))FG=1; puts(FG?"Yes!":"No!");}int T;int main(){ scanf("%d",&T); while(T--)work(); return 0;}