Pipe
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 9493   Accepted: 2877

Description

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

  1. 4
  2. 0 1
  3. 2 2
  4. 4 1
  5. 6 4
  6. 6
  7. 0 1
  8. 2 -0.6
  9. 5 -4.45
  10. 7 -5.57
  11. 12 -10.8
  12. 17 -16.55
  13. 0

Sample Output

  1. 4.67
  2. Through all the pipe.

Source

题目大意:给出一个管道,让一束光穿过,找出一个穿过距离最长的,然后求出这个穿过距离最长的与管壁的交点的x坐标,如果可以完整的穿过整个管道,输出Through all the pipe.
思路: 枚举光线是否可以穿过每一个拐点官腔,也就是拐点所在位置的竖直线段,如果不能穿过说明它肯定与管壁相交,计算交点,如果都能相交,这时就是可以穿过整个管道。
注:刚开始枚举的时候枚举的特别麻烦,是直接枚举光线方向,从入口一次加0.01的枚举,判断特殊位置的时候特别麻烦
  1. /*************************************************************************
  2. > File Name: poj_1039.cpp
  3. > Author: Howe_Young
  4. > Mail: 1013410795@qq.com
  5. > Created Time: 2015年05月01日 星期五 09时43分46秒
  6. ************************************************************************/
  7.  
  8. #include <cstdio>
  9. #include <iostream>
  10. #include <cstring>
  11. #include <cmath>
  12. #include <cstdlib>
  13. #include <algorithm>
  14. #define EPS 1e-8
  15. #define INF 1e6
  16. using namespace std;
  17. struct point{
  18. double x, y;
  19. };
  20. const int maxn = ;
  21. point p[maxn];
  22. int n;
  23. int sgn(double x)
  24. {
  25. if (fabs(x) < EPS)
  26. return ;
  27. return x < ? - : ;
  28. }
  29. double x_multi(point p1, point p2, point p3)
  30. {
  31. return (p3.x - p1.x) * (p2.y - p1.y) - (p2.x - p1.x) * (p3.y - p1.y);
  32. }
  33. void get_intersection(point p1, point p2, point p3, point p4, double &x, double &y)
  34. {
  35. double a1, b1, c1, a2, b2, c2;//求交点过程
  36. a1 = (p2.y - p1.y) * 1.0;
  37. b1 = (p1.x - p2.x) * 1.0;
  38. c1 = (p2.x * p1.y - p1.x * p2.y) * 1.0;
  39. a2 = (p4.y - p3.y) * 1.0;
  40. b2 = (p3.x - p4.x) * 1.0;
  41. c2 = (p3.y * p4.x - p4.y * p3.x) * 1.0;
  42. x = (b1 * c2 - b2 * c1) / (b2 * a1 - b1 * a2);
  43. y = (a1 * c2 - c1 * a2) / (a2 * b1 - a1 * b2);
  44. }
  45.  
  46. bool check(point p1, point p2, point p3, point p4)//p1p2是否穿过竖着的p3p4,查看这条线是否与每一个拐角处上下连接的线段都相交,包括端点
  47. {
  48. double d1 = x_multi(p1, p2, p3);
  49. double d2 = x_multi(p1, p2, p4);
  50. return d1 * d2 <= ;
  51. }
  52. bool check2(point p1, point p2, point p3, point p4)//同理看p3, p4这两个点是否在p1p2两侧,端点不算
  53. {
  54. double d1 = x_multi(p1, p2, p3);
  55. double d2 = x_multi(p1, p2, p4);
  56. return d1 * d2 < ;
  57. }
  58. point does(point p1)//它的对应的下一个端点
  59. {
  60. p1.y--;
  61. return p1;
  62. }
  63. int main()
  64. {
  65. while (~scanf("%d", &n) && n)
  66. {
  67. for (int i = ; i < n; i++)
  68. {
  69. scanf("%lf %lf", &p[i].x, &p[i].y);
  70. }
  71. point p0;
  72. double ans = p[].x;
  73. for (int i = ; i < n; i++)
  74. {
  75. for (int j = ; j < n; j++)
  76. {
  77. if (i == j)
  78. continue;
  79. if (check(p[i], does(p[j]), p[], does(p[])))//如果光线可以从入口射进来
  80. {
  81. for (int k = ; k < n; k++)
  82. {
  83. if (!check(p[i], does(p[j]), p[k], does(p[k])))//如果走到k点这个拐点与管壁相交了,找出相交的点来
  84. {
  85. if (check2(p[i], does(p[j]), p[k], p[k - ]))//如果与上壁相交
  86. {
  87. get_intersection(p[i], does(p[j]), p[k], p[k - ], p0.x, p0.y);
  88. if (ans < p0.x)
  89. ans = p0.x;
  90. break;
  91. }
  92. if (check2(p[i], does(p[j]), does(p[k]), does(p[k - ])))//如果与下壁相交
  93. {
  94. get_intersection(p[i], does(p[j]), does(p[k]), does(p[k - ]), p0.x, p0.y);
  95. if (ans < p0.x)
  96. ans = p0.x;
  97. break;
  98. }//如果都不相交的话,那么说明是与上一段的端点相交
  99. if (ans < p[k - ].x)
  100. ans = p[k - ].x;
  101. break;
  102. }
  103. if (k == n - )//如果走到最后都没break,也就是相交,那么说明可以通过这个管道,直接让他等于最后的x坐标
  104. {
  105. ans = p[n - ].x;
  106. }
  107. }
  108. }
  109. }
  110. }
  111. if (sgn(ans - p[n - ].x) == )
  112. {
  113. puts("Through all the pipe.");
  114. }
  115. else
  116. printf("%.2f\n", ans);
  117. }
  118. return ;
  119. }

POJ 1039 Pipe 枚举线段相交的更多相关文章

  1. POJ 1039 直线和线段相交

    题意: 题意很好理解,从左边射过来的光线,最远能经过管道到右边多少距离. 分析: 光线一定经过一个上端点和一个下端点,这一点很容易想到.然后枚举上下端点即可 #include <iostream ...

  2. POJ 1039 Pipe【经典线段与直线相交】

    链接: http://poj.org/problem?id=1039 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=22013#probl ...

  3. 简单几何(直线与线段相交) POJ 1039 Pipe

    题目传送门 题意:一根管道,有光源从入口发射,问光源最远到达的地方. 分析:黑书上的例题,解法是枚举任意的一个上顶点和一个下顶点(优化后),组成直线,如果直线与所有竖直线段有交点,则表示能穿过管道. ...

  4. POJ 1039 Pipe(直线和线段相交判断,求交点)

    Pipe Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 8280   Accepted: 2483 Description ...

  5. poj 1066(枚举+线段相交)

    Treasure Hunt Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 6328   Accepted: 2627 Des ...

  6. POJ 1408 Fishnet【枚举+线段相交+叉积求面积】

    题目: http://poj.org/problem?id=1408 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=22013#probl ...

  7. POJ - 1039 Pipe(计算几何)

    http://poj.org/problem?id=1039 题意 有一宽度为1的折线管道,上面顶点为(xi,yi),所对应的下面顶点为(xi,yi-1),假设管道都是不透明的,不反射的,光线从左边入 ...

  8. POJ 1066 Treasure Hunt(线段相交判断)

    Treasure Hunt Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 4797   Accepted: 1998 Des ...

  9. POJ 1066--Treasure Hunt(判断线段相交)

    Treasure Hunt Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7857   Accepted: 3247 Des ...

随机推荐

  1. 3.1决策树理论--python深度机器学习

    参考彭亮老师的视频教程:转载请注明出处及彭亮老师原创 视频教程: http://pan.baidu.com/s/1kVNe5EJ   0. 机器学习中分类和预测算法的评估:   准确率 速度 强壮行 ...

  2. 那些年被我坑过的Python——摩拳擦掌(第三章)

    集合类型: 集合类型中的元素是唯一的! 集合的定义与赋值: set_1 = set([1, 3, 5, 7, 2]) set_2 = set([2, 4, 6, 8, 3]) 集合的运算操作 # 交集 ...

  3. uboot的jumptable_init函数分析

    一.函数说明 函数功能:安装系统函数指针 函数位置:common/exports.c 二.函数分析 void jumptable_init (void) { int i; gd->jt = (v ...

  4. sql的执行顺序

    sql的一般执行顺序(8)SELECT (9)DISTINCT (11)<Top Num> <select list>(1)FROM [left_table](3)<jo ...

  5. 在VS2008.Net下使用WPF开发Web应用程序

    原文地址:http://hankjin.blog.163.com/blog/static/33731937200922353623434/ 胖客户端的好处是可以轻易的实现绚丽的效果, 而瘦客户端则需要 ...

  6. seajs打包部署工具spm的使用总结

    相信使用seajs的好处大家都是知道的,接触seajs好像是在半年前,当时还不知道页面阻塞问题,这里不带多余的话了. seajs实现了模块化的开发,一个网站如果分了很多很多模块的话,等开发完成了,发现 ...

  7. BZOJ 3872 Ant colony

    Description There is an entrance to the ant hill in every chamber with only one corridor leading int ...

  8. Windows Server 2012 R2里十个极好的新功能

    Windows Server 2012 R2具备的众多新特点大大的增强了操作系统的功能性,同时也是在Windows Server 2012原有功能上的拓展.这里整理出Windows Server 20 ...

  9. CN消息的来源——父窗口不知道怎么处理,于是把这个消息加上CN_BASE在分发到实际的子窗体

    VCL存在一些非API消息以供其内部使用,为什么要这样做呢?这要从WM_COMMAND & WM_NOTIFY消息说起,我们说WM_COMMAND消息并不是直接发给实际产生消息的窗体,而是发送 ...

  10. mysql 安装1

    Linux 安装mysql.tar.gz包(2012-09-28 19:25:06) 标签: it 分类: linux学习编 我用的mysql的版本的是:mysql--linux-i686-icc-g ...