码迷,mamicode.com
首页 > 其他好文 > 详细

Pipe

时间:2017-07-16 10:05:46      阅读:211      评论:0      收藏:0      [点我收藏+]

标签:print   message   line   ref   端点   pipe   sage   pac   closed   

Pipe

The GX Light Pipeline Company started to prepare bent pipes for the new transgalactic light pipeline. During the design phase of the new pipe shape the company ran into the problem of determining how far the light can reach inside each component of the pipe. Note that the material which the pipe is made from is not transparent and not light reflecting. 
技术分享

Each pipe component consists of many straight pipes connected tightly together. For the programming purposes, the company developed the description of each component as a sequence of points [x1; y1], [x2; y2], . . ., [xn; yn], where x1 < x2 < . . . xn . These are the upper points of the pipe contour. The bottom points of the pipe contour consist of points with y-coordinate decreased by 1. To each upper point [xi; yi] there is a corresponding bottom point [xi; (yi)-1] (see picture above). The company wants to find, for each pipe component, the point with maximal x-coordinate that the light will reach. The light is emitted by a segment source with endpoints [x1; (y1)-1] and [x1; y1] (endpoints are emitting light too). Assume that the light is not bent at the pipe bent points and the bent points do not stop the light beam.

Input

The input file contains several blocks each describing one pipe component. Each block starts with the number of bent points 2 <= n <= 20 on separate line. Each of the next n lines contains a pair of real values xi, yi separated by space. The last block is denoted with n = 0.

Output

The output file contains lines corresponding to blocks in input file. To each block in the input file there is one line in the output file. Each such line contains either a real value, written with precision of two decimal places, or the message Through all the pipe.. The real value is the desired maximal x-coordinate of the point where the light can reach from the source for corresponding pipe component. If this value equals to xn, then the message Through all the pipe. will appear in the output file.

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 }
View Code

 

Pipe

标签:print   message   line   ref   端点   pipe   sage   pac   closed   

原文地址:http://www.cnblogs.com/whc200305/p/7189534.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!