判断线段和直线相交 POJ 3304
1 // 判断线段和直线相交 POJ 3304 2 // 思路: 3 // 如果存在一条直线和所有线段相交,那么平移该直线一定可以经过线段上任意两个点,并且和所有线段相交。 4 5 #include <cstdio> 6 #include <cstring> 7 #include <iostream> 8 #include <algorithm> 9 #include <map> 10 #include <set> 11 #include <queue> 12 #include <stdlib.h> 13 #include <cmath> 14 using namespace std; 15 typedef long long LL; 16 const LL inf = 1e18; 17 const int N = 5000; 18 const double eps = 1e-8; 19 20 int sgn(double x){ 21 if(fabs(x)<eps) return 0; 22 if(x<0) return -1; 23 return 1; 24 } 25 26 struct Point{ 27 double x,y; 28 Point(){} 29 Point(double _x,double _y){ 30 x=_x;y=_y; 31 } 32 Point operator -(const Point &b)const{ 33 return Point(x-b.x,y-b.y); 34 } 35 double operator *(const Point &b)const{ 36 return x*b.x+y*b.y; 37 } 38 double operator ^(const Point &b)const{ 39 return x*b.y-y*b.x; 40 } 41 }; 42 43 struct Line{ 44 Point s,e; 45 Line(){} 46 Line(Point _s,Point _e){ 47 s=_s,e=_e; 48 } 49 }; 50 51 double xmult(Point p0,Point p1,Point p2){ 52 return (p1-p0)^(p2-p0); 53 } 54 55 bool Seg_inter_line(Line l1,Line l2){ 56 return sgn(xmult(l2.s,l1.s,l1.e))*sgn(xmult(l2.e,l1.s,l1.e))<=0; 57 } 58 59 double dist(Point a,Point b){ 60 return sqrt((a-b)*(a-b)); 61 } 62 Line line[N]; 63 bool work(Line l1,int n){ 64 if(sgn(dist(l1.s,l1.e))==0) return false; 65 for(int i=0;i<n;i++){ 66 if(Seg_inter_line(l1,line[i])==false) return false; 67 } 68 return true; 69 } 70 int main(){ 71 int n,T; 72 scanf("%d",&T); 73 while(T--){ 74 scanf("%d",&n); 75 double x1,y1,x2,y2; 76 for(int i=0;i<n;i++){ 77 scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); 78 line[i]=Line(Point(x1,y1),Point(x2,y2)); 79 } 80 bool flag=false; 81 for(int i=0;i<n;i++){ 82 for(int j=0;j<n;j++){ 83 if(work(Line(line[i].s,line[j].e),n)||work(Line(line[i].s,line[j].s),n)||work(Line(line[i].e,line[j].e),n)||work(Line(line[i].e,line[j].s),n)){ 84 flag=true; 85 break; 86 } 87 } 88 if(flag) break; 89 } 90 if(flag) puts("Yes!"); 91 else puts("No!"); 92 } 93 return 0; 94 }