POJ-1039 Pipe 枚举+线段相交判断
题目链接:http://poj.org/problem?id=1039
比较有意思的一道题目,用光线射入一个管道,文最多能射多远。在最优解中一定存在光线紧挨着管道弯折点的情况,题目数据比较小,因此我们可以枚举管道上的两点,然后求出这条光线能入射的最远距离。只要判断当前直线管道壁是否相交,这里可以判断直线是否与对应的两个弯折点相交,如果相交,则直线合法,反之亦然,这样做方便处理。
1 //STATUS:C++_AC_32MS_188KB 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<string.h> 5 #include<math.h> 6 #include<iostream> 7 #include<string> 8 #include<algorithm> 9 #include<vector> 10 #include<queue> 11 #include<stack> 12 using namespace std; 13 #define LL __int64 14 #define pii pair<int,int> 15 #define Max(a,b) ((a)>(b)?(a):(b)) 16 #define Min(a,b) ((a)<(b)?(a):(b)) 17 #define mem(a,b) memset(a,b,sizeof(a)) 18 #define lson l,mid,rt<<1 19 #define rson mid+1,r,rt<<1|1 20 const int N=30,M=1000000,INF=0x3f3f3f3f,MOD=1999997; 21 const LL LLNF=0x3f3f3f3f3f3f3f3fLL; 22 const double DNF=100000000; 23 24 struct Node{ 25 double x,y; 26 }nod[N]; 27 struct Line{ 28 double x1,y1,x2,y2; 29 }lin[N]; 30 int n; 31 32 void linef(Line &a,double &A,double &B,double &C) 33 { 34 A=-(a.y1-a.y2); 35 B=a.x1-a.x2; 36 C=-A*a.x1-B*a.y1; 37 } 38 39 int las(Line &a,Line &b) 40 { 41 Node r1,r0,r2; 42 r1.x=a.x1-b.x1; 43 r1.y=a.y1-b.y1; 44 r0.x=b.x2-b.x1; 45 r0.y=b.y2-b.y1; 46 r2.x=a.x2-b.x1; 47 r2.y=a.y2-b.y1; 48 if( ((r1.x*r0.y)-(r0.x*r1.y)) 49 *((r2.x*r0.y)-(r0.x*r2.y))<=0 )return 1; 50 else return 0; 51 } 52 53 double getx(Line &a,Line &b) 54 { 55 double a1,b1,c1,a2,b2,c2; 56 linef(a,a1,b1,c1); 57 linef(b,a2,b2,c2); 58 return (c2*b1-c1*b2)/(a1*b2-a2*b1); 59 } 60 61 int main() 62 { 63 // freopen("in.txt","r",stdin); 64 int i,j,k,ok; 65 double ans; 66 Line t,lz; 67 while(~scanf("%d",&n) && n) 68 { 69 ok=0; 70 ans=-DNF; 71 for(i=0;i<n;i++){ 72 scanf("%lf%lf",&nod[i].x,&nod[i].y); 73 lin[i].x1=lin[i].x2=nod[i].x; 74 lin[i].y1=nod[i].y-1;lin[i].y2=nod[i].y; 75 } 76 for(i=0;i<n;i++){ 77 for(j=0;j<n;j++){ 78 if(i==j)continue; 79 lz.x1=nod[i].x,lz.y1=nod[i].y; 80 lz.x2=nod[j].x,lz.y2=nod[j].y-1; 81 for(k=0;k<n;k++){ 82 if(las(lin[k],lz))continue; 83 else { 84 if(k>0){ 85 t.x1=nod[k-1].x,t.y1=nod[k-1].y; 86 t.x2=nod[k].x,t.y2=nod[k].y; 87 ans=Max(ans,getx(lz,t)); 88 t.y1--,t.y2--; 89 ans=Max(ans,getx(lz,t)); 90 } 91 break; 92 } 93 } 94 if(k==n){ok=1;break;} 95 } 96 } 97 98 if(ok)printf("Through all the pipe.\n"); 99 else printf("%.2lf\n",ans); 100 } 101 return 0; 102 }