标签:print message line ref 端点 pipe sage pac closed
Pipe
Input
Output
Sample Input
4 0 1 2 2 4 1 6 4 6 0 1 2 -0.6 5 -4.45 7 -5.57 12 -10.8 17 -16.55 0
Sample Output
4.67 Through all the pipe.
题目的大意是,描述一个等宽管道,会折来折去,让你求一束光(未确定)最远能射到哪里.(光是直射的,不反射,折射)
那么,光线必定经过两个折点,并且一个是上端点,一个是上端点,可以运用反证法来证明这是正确的.
当我们枚举了两个端点以后,已经确定了这条直线,只要判断与其他线段的关系就行了.怎么判断.
首先,要保证这条直线能穿过下一个"口"子,同时,也不能与两个管壁有相交.当然,要注意<=和<,>和>=的问题,很关键.
最后如果全部都成功,那么光线就可以通过所有pipe了.
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 using namespace std; 7 const double eps=1e-8; 8 int n; double Mx; 9 struct point{double x,y;}a[50],focal; 10 point operator - (point P,point Q){point ret; ret.x=P.x-Q.x,ret.y=P.y-Q.y; return ret;} 11 double cross(point P,point Q){return P.x*Q.y-P.y*Q.x;} 12 bool cross_entrance(point p1,point p2,point p3,point p4){ 13 double f1=cross(p3-p1,p2-p1); 14 double f2=cross(p4-p1,p2-p1); 15 return f1*f2<=0; 16 } 17 bool intersect(point p1,point p2,point p3,point p4){ 18 double f1=cross(p3-p1,p2-p1); 19 double f2=cross(p4-p1,p2-p1); 20 return !(f1*f2>=0); 21 } 22 void calc(point p1,point p2,point p3,point p4,point &focal){ 23 double f=((p1.x-p3.x)*(p3.y-p4.y)-(p1.y-p3.y)*(p3.x-p4.x))/((p1.x-p2.x)*(p3.y-p4.y)-(p1.y-p2.y)*(p3.x-p4.x)); 24 focal=p1,focal.x+=(p2.x-p1.x)*f,focal.y+=(p2.y-p1.y)*f; 25 } 26 point down(point p){p.y--; return p;} 27 int main(){ 28 for (scanf("%d",&n); n; scanf("%d",&n)){ 29 for (int i=0; i<n; i++) scanf("%lf%lf",&a[i].x,&a[i].y); Mx=a[0].x; 30 for (int i=0; i<n; i++) 31 for (int j=0; j<n; j++) 32 if (cross_entrance(a[i],down(a[j]),a[0],down(a[0]))){ 33 int no=n; 34 for (int k=1; k<n; k++){ 35 if(!cross_entrance(a[i],down(a[j]),a[k],down(a[k]))){ 36 if (intersect(a[i],down(a[j]),a[k],a[k-1])){ 37 calc(a[i],down(a[j]),a[k],a[k-1],focal); 38 Mx=max(Mx,focal.x),no=k; break; 39 } 40 if (intersect(a[i],down(a[j]),down(a[k]),down(a[k-1]))){ 41 calc(a[i],down(a[j]),down(a[k]),down(a[k-1]),focal); 42 Mx=max(Mx,focal.x),no=k; break; 43 } 44 Mx=max(Mx,a[k-1].x); no=k; break; 45 } 46 } 47 if (no==n){Mx=a[n-1].x; break;} 48 } 49 if(Mx>=a[n-1].x) puts("Through all the pipe."); else printf("%.2lf\n",Mx); 50 } 51 return 0; 52 }
标签:print message line ref 端点 pipe sage pac closed
原文地址:http://www.cnblogs.com/whc200305/p/7189534.html