注意:
不碰任何顶点-----(上下移动)>碰一个顶点-----(绕此顶点旋转)>碰两个顶点-----(绕前后两个顶点旋转)>碰上下各一个顶点
其中:判断i,j是否被某壁阻挡,可通过判断是否与垂直线段相交判断!!!!!!!!!!
View Code
1 /* 2 几何+直线相交+求交点 3 */ 4 #include<stdio.h> 5 #include<string.h> 6 #include<stdlib.h> 7 #include<algorithm> 8 using namespace std; 9 const int maxn = 24; 10 const double inf= 99999999.0; 11 const double eps = 1e-8; 12 struct Point{ 13 double x,y; 14 }up[ maxn ],down[ maxn ]; 15 int sig( double d ){ 16 if( d>eps ) return 1; 17 if( d<-eps ) return -1; 18 return 0; 19 } 20 double xmult( Point a,Point b,Point c ){ 21 return ( b.x-a.x )*( c.y-a.y )-( b.y-a.y )*( c.x-a.x ); 22 } 23 bool check( Point a,Point b,Point c,Point d ){ 24 return (( sig(xmult(a,b,c)) )*( sig(xmult(a,b,d)) )<=0); 25 } 26 double Intersection( Point a,Point b,Point c,Point d ){ 27 double s1 = xmult( a,b,c ); 28 double s2 = xmult( a,b,d ); 29 int t1,t2; 30 t1 = sig( s1 ),t2 = sig( s2 ); 31 if( t1*t2<0 ){ 32 return ( c.x*s2-d.x*s1 )/(s2-s1);//return x 坐标 33 //(c.y*s2-d.y*s1)/(s2-s1) 34 } 35 if( t1*t2==0 ){ 36 if( t1==0 ) return c.x; 37 if( t2==0 ) return d.x; 38 } 39 return -inf; 40 } 41 int main(){ 42 int n; 43 while( scanf("%d",&n)==1,n ){ 44 for( int i=1;i<=n;i++ ){ 45 scanf("%lf%lf",&up[ i ].x,&up[ i ].y); 46 down[ i ].x = up[ i ].x; 47 down[ i ].y = up[ i ].y-1.0; 48 } 49 double ans = -inf; 50 bool flag = false;//是否能贯通两端 51 for( int i=1;i<=n;i++ ){ 52 for( int j=1;j<=n;j++ ){ 53 if( i!=j ){ 54 int k; 55 for( k=1;k<=n;k++ ){ 56 if( check( up[i],down[j],up[k],down[k] )==true ){}//与垂直的线段相交true 57 else break; 58 } 59 if( k>n ){ 60 flag = true; 61 break; 62 } 63 else if( k>max(i,j) ){ 64 double pos; 65 pos = Intersection( up[i],down[j],up[k],up[k-1] ); 66 if( pos>ans ) ans = pos; 67 pos = Intersection( up[i],down[j],down[k],down[k-1] ); 68 if( pos>ans ) ans = pos; 69 //因为不知道ij是和上管壁相交还是下管壁相交 70 } 71 } 72 } 73 if( flag==true ) break; 74 } 75 if( flag == true ) printf("Through all the pipe.\n"); 76 else printf("%.2lf\n",ans); 77 } 78 return 0; 79 }