Segments
题目链接:https://vjudge.net/problem/POJ-3304
题目:
题意:问是否存在一条直线,使所有线段到这条直线的投影至少有一个交点。
思路:就是看有没有一条直线与所有的线段相交,由于数据很小,因此可以暴力求解,将题目给的所有点用结构体存起来,然后任意两个端点相连为一条直线,判断该直线是否与所有的线段相交即可,在设定为直线前先判断该两点之间距离是否小于1e-8,若小于则可以看作为一点,不可组成直线,继续与其他点成为直线,暴力判断。
// // Created by HJYL on 2020/1/12. // #include<stdio.h> #include<math.h> #include<string.h> #define eps 1e-8 #define pi 3.141592653589793 const int maxn=1e5+10; using namespace std; struct Point{ double x,y; Point(double a=0,double b=0){x=a;y=b;} }; typedef Point Vector; struct Line{ double a,b,c,angle; Point p1,p2; Line(Point s,Point e) { a=s.y-e.y; b=e.x-s.x; c=s.x*e.y-e.x*s.y; angle=atan2(e.y-s.y,e.x-s.x); p1=s;p2=e; } Line(){} }; struct Segment { Point s,e; Segment(Point a,Point b){s=a;e=b;} Segment(double x1,double y1,double x2,double y2) { s=Point(x1,y1); e=Point(x2,y2); } Segment(){} }; Vector operator + (Point a,Point b) { return Vector(a.x+b.x,a.y+b.y); } Vector operator - (Point a,Point b) { return Vector(a.x-b.x,a.y-b.y); } Vector operator * (Point a,double k) { return Vector(a.x*k,a.y*k); } Vector operator / (Point a,double k) { return Vector(a.x/k,a.y/k); } double Cross(Point &sp, Point &ep, Point &op) { return (sp.x-op.x)*(ep.y-op.y)-(ep.x-op.x)*(sp.y-op.y); } double Cross(Vector a,Vector b) { return a.x*b.y-b.x*a.y; } int epssgn(double x) { if(fabs(x)<eps) return 0; else return x<0?-1:1; } double dis(Point a,Point b) { return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } int IsLineIntersectSegment(Point p1,Point p2,Point s,Point e) { if (Cross(p1,p2,s)*Cross(p1,p2,e)>eps) return 0; else return 1; } int main() { //freopen("text","r",stdin); int T; scanf("%d",&T); while(T--) { int n; scanf("%d",&n); Point ll[maxn]; double xx,yy,xx1,yy1; int pos=0; for(int i=0;i<n;i++) { scanf("%lf%lf%lf%lf",&xx,&yy,&xx1,&yy1); ll[pos].x=xx;ll[pos].y=yy; pos++; ll[pos].x=xx1;ll[pos].y=yy1; pos++; } if(n==1||n==2) printf("Yes! "); else { bool ff=false; for (int i = 0; i < pos; i++) { for (int j = 0; j < pos; j++) { if (i == j) continue; if (dis(ll[i], ll[j]) < eps) continue; bool flag = false; for (int t = 0; t < n; t++) { if(!IsLineIntersectSegment(ll[i],ll[j],ll[t*2],ll[t*2+1])) { flag=true; break; } } if(!flag) { ff=true; break; } } if(ff) break; } if(ff) printf("Yes! "); else printf("No! "); } } return 0; }