poj 1039 Pipe (直線與線段相交判斷+列舉端點)
阿新 • • 發佈:2018-11-16
題目連結:傳送門
題意:有一條寬度為1(指的是上下管壁縱座標之差,不是管道真實的寬度)的折線形管道,管道壁不透光不反光,求從管道一頭射入一束光線,光線在管道內沿直線傳播最遠能傳播多遠(橫座標能到達的最大值)。
輸入:每個測試用例一個數據塊,第一個整數為折點數(2到20之間),接下來每行一個折點座標(即上圖中的一個點[x,y],x互不相等,按增序排列),表示管道的上邊界折點,對應的下邊界折點為[x,y-1].折點數位0時表示輸入結束。
輸出:每次用例輸出一行,若光線能穿透整個管道,輸出Through all the pipe.否則輸出能到達的x值,保留兩位小數。
題解:直接列舉
#include<cstdio> #include<algorithm> #include<cstring> #include<cmath> using namespace std; struct point { double x,y; point(){} point(double _x,double _y){ x=_x;y=_y; } }; point operator + (point a,point b) {return point(a.x+b.x,a.y+b.y);} point operator - (point a,point b) {return point(a.x-b.x,a.y-b.y);} point operator * (point a,double p) { return point(a.x*p,a.y*p);} point operator / (point a,double p){ return point(a.x/p,a.y/p);} bool operator < (const point &a,const point &b){ return a.x<b.x||(a.x==b.x&&a.y<b.y); } const double esp=1e-8; int dcmp(double x){ if(fabs(x)<esp) return 0; else return x<0?-1:1; } bool operator ==(const point &a,const point &b){ return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0; } double Cross(point A,point B) { return A.x*B.y-A.y*B.x;} point Getlinenode(point P,point v,point Q,point w){ ///兩引數方程求交點,(點,向量,點,向量) point u=P-Q; double t=Cross(w,u)/Cross(v,w); return P+v*t; } bool isCross(point s1,point e1,point s2,point e2)///判斷直線與線段是否相交 { ///首先判斷向量s2e2 跨立 向量s1e1 double c1=Cross(s2-s1,e1-s1),c2=Cross(e1-s1,e2-s1); ///==0表示,相交於端點也認定為相交 if(dcmp(c1*c2)>=0) return true; return false; } point p1[30],p2[30]; int main() { int n; while(scanf("%d",&n)&&n) { double a,b; for(int i=0;i<n;i++){ scanf("%lf%lf",&a,&b); p1[i]=point(a,b); p2[i]=point(a,b-1); } bool flag=true; double ans=p1[0].x; for(int i=0;i<n&&flag;i++) { for(int j=0;j<n&&flag;j++) { if(i==j) continue; int k; for( k=0;k<n;k++){ if(!isCross(p1[i],p2[j],p1[k],p2[k])){ ///判斷直線ij與線段k是否相交 // break; } } if(k==n) { flag=false;break; } else if(k>max(i,j)){ point item=Getlinenode(p1[i],p1[i]-p2[j],p1[k],p1[k]-p1[k-1]); if(item.x>ans) ans=item.x; item=Getlinenode(p1[i],p1[i]-p2[j],p2[k],p2[k]-p2[k-1]); if(item.x>ans) ans=item.x; // printf("ans=%.2f,k=%d\n",ans,k); } } } if(flag){ printf("%.2f\n",ans); } else printf("Through all the pipe.\n"); } return 0; }