http://poj.org/problem?id=3304
等价于是否存在一条直线穿过所有线段
判断直线与线段是否相交:
首先用两点p1,p2确定了一条直线 在用p1,p2分别与计算线段两个端点计算叉乘即可 ,叉乘之积>0就说明线段两端点在直线的同侧,也就是直线不经过此线段
注意顺序不要搞反了
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; const double eps=1e-8; const int maxn=100004; int dcmp(double x) { if(fabs(x) < eps) return 0; return x < 0 ? -1 : 1; } #define Point Vector struct Vector{ double x,y; Vector(double x=0,double y=0):x(x),y(y){}; Vector operator + (const Vector &A) const{ return Vector(x+A.x,y+A.y); } Vector operator - (const Vector &A) const{ return Vector(x-A.x,y-A.y); } Vector operator * (const double &A) const{ return Vector(x*A,y*A); } Vector operator / (const double &A) const{ return Vector(x/A,y/A); } bool operator == (const Vector &A) const{ return dcmp(x-A.x)==0&&dcmp(y-A.y)==0; } }; struct Line{ Point p1,p2; Line(){}; Line(Point p1,Point p2):p1(p1),p2(p2){} }li[maxn]; bool operator < (Line l1,Line l2){ if(l1.p1.x==l2.p1.x) return l1.p1.y<l2.p1.y; else return l1.p1.x<l2.p1.x; } int ans[maxn],num[maxn],n,m; double U,L,R,D; double PolarAngle(Vector A){ return atan2(A.y,A.x); } Vector rotate(Vector &A,double a){ return A=Vector(A.x*cos(a)-A.y*sin(a),A.x*sin(a)+A.y*cos(a)); } double Dot(Vector A,Vector B){ return A.x*B.x+A.y*B.y; } double Cross(Vector A,Vector B){ return A.x*B.y-A.y*B.x; } double dis(Point p1,Point p2){ return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)); } bool solve(Point p1,Point p2){ if(dcmp(dis(p1,p2))==0) return false; for(int i=1;i<=n;i++){ if(dcmp(Cross(li[i].p1-p1,li[i].p1-p2)*Cross(li[i].p2-p1,li[i].p2-p2))>0) return false; } return true; } int main(){ int T;scanf("%d",&T); while(T--){ scanf("%d",&n); for(int i=1;i<=n;i++){ Point p1,p2; scanf("%lf%lf%lf%lf",&p1.x,&p1.y,&p2.x,&p2.y); li[i]=Line(p1,p2); } if(n==1) {printf("Yes!\n");continue;} int flag=0; for(int i=1;i<=n;i++){ if(solve(li[i].p1,li[i].p2)) { //cout<<i<<endl; printf("Yes!\n");flag=1; break; } for(int j=i+1;j<=n;j++){ if(solve(li[i].p1,li[j].p1)) { printf("Yes!\n");flag=1; break; } if(solve(li[i].p1,li[j].p2)) { printf("Yes!\n");flag=1; break; } if(solve(li[i].p2,li[j].p1)) { printf("Yes!\n");flag=1; break; } if(solve(li[i].p2,li[j].p2)) { printf("Yes!\n");flag=1; break; } } if(flag) break; } if(!flag) printf("No!\n"); } }
原文地址:https://www.cnblogs.com/wifimonster/p/10323946.html
时间: 2024-10-07 23:25:35