poj 1039 Pipe(几何基础)

Pipe

Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 9932   Accepted: 3045

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

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.

Source

Central Europe 1995

【思路】

线段直线相交。

如果一条直线没有经过两个拐点一定不是最优的直线,可以通过旋转移动使之更优。

枚举上线顶点,判断相交,求出交点。

【代码】

 1 #include<cmath>
 2 #include<cstdio>
 3 #include<algorithm>
 4 using namespace std;
 5 const int N = 22;
 6 const double eps = 1e-8;
 7
 8 struct Pt{
 9     double x, y;
10 }a[N], b[N];
11 struct Line{ double a, b, c; };
12 int n;
13 double ans;
14
15 double mult(Pt sp, Pt ep, Pt op){
16     return (sp.x-op.x)*(ep.y-op.y) - (ep.x-op.x)*(sp.y-op.y);
17 }
18 Line getLine(Pt p1, Pt p2){
19     Line ans;
20     ans.a = p1.y - p2.y;
21     ans.b = p2.x - p1.x;
22     ans.c = p1.x*p2.y - p2.x*p1.y;
23     return ans;
24 }
25
26 bool solve(Pt p1, Pt p2, int e){
27     int i, flag;
28     for(i = 0; i < n-1; i ++) {
29         if(mult(p2, a[i], p1) < -eps || mult(p2, a[i+1], p1) < -eps){
30             flag = 1; break;
31         }
32         if(mult(p2, b[i], p1) > eps || mult(p2, b[i+1], p1) > eps){
33             flag = 2; break;
34         }
35     }
36     if(i == n-1) return true;   //  没有与任何的管道相交,Through all the pipe.
37     if(i < e) return false;     //  光线不合法。
38     Line l1, l2;                //  光线合法,求出射到的最远距离。
39     l1 = getLine(p1, p2);
40     if(flag == 1) l2 = getLine(a[i], a[i+1]);
41     else l2 = getLine(b[i], b[i+1]);
42     ans = max(ans, (l1.b*l2.c-l2.b*l1.c)/(l1.a*l2.b-l2.a*l1.b));
43     return false;
44 }
45
46 int main(){
47     int i, j;
48     while(scanf("%d", &n) && n){
49         for(i = 0; i < n; i ++){
50             scanf("%lf%lf", &a[i].x, &a[i].y);
51             b[i].x = a[i].x;
52             b[i].y = a[i].y - 1;
53         }
54         ans = -1e9;
55         bool flag = 0;
56         if(n < 3) flag = 1;
57         for(i = 0; i < n; i ++) {
58             for(j = i + 1; j < n; j ++){
59                 flag = solve(a[i], b[j], j);
60                 if(flag) break;
61                 flag = solve(b[i], a[j], j);
62                 if(flag) break;
63             }
64             if(flag) break;
65         }
66         if(flag) puts("Through all the pipe.");
67         else printf("%.2lf\n", ans);
68     }
69     return 0;
70 }
时间: 2024-10-27 12:28:19

poj 1039 Pipe(几何基础)的相关文章

POJ - 1039 Pipe(计算几何)

http://poj.org/problem?id=1039 题意 有一宽度为1的折线管道,上面顶点为(xi,yi),所对应的下面顶点为(xi,yi-1),假设管道都是不透明的,不反射的,光线从左边入口处的(x1,y1),(x1,y1-1)之间射入,向四面八方传播,求解光线最远能传播到哪里(取x坐标)或者是否能穿透整个管道. 分析 最远的直线必定经过一个上折点和一个下折点.枚举这两个点即可. #include <iostream> #include <stdio.h> #inclu

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

题目传送门 题意:一根管道,有光源从入口发射,问光源最远到达的地方. 分析:黑书上的例题,解法是枚举任意的一个上顶点和一个下顶点(优化后),组成直线,如果直线与所有竖直线段有交点,则表示能穿过管道. /************************************************ * Author :Running_Time * Created Time :2015/10/31 星期六 10:28:12 * File Name :POJ_1039.cpp ***********

POJ 1039 Pipe 枚举线段相交

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 th

poj 1039 Pipe (计算几何)

Pipe Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 9110   Accepted: 2755 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 th

POJ 1039 Pipe

题意:一根管子,中间有一些拐点,给出拐点的上坐标,下坐标为上坐标的纵坐标减1,管子不能透过光线也不能折射光线,问光线能射到最远的点的横坐标. 解法:光线射到最远处的时候一定最少经过两个拐点,枚举每两个顶点,判断最远光线射到的位置.代码姿势不够优美……都是眼泪啊 代码: #include<stdio.h> #include<iostream> #include<algorithm> #include<string> #include<string.h&g

POJ 1039

一条直线,必定可以通过旋转和平移使得它和一个上顶点一下顶点相切,这样的直线是最优的.因为这样能确定了直线所能到达的最远X.这样的两个顶点就规定了它的上下界, 所以,枚举上下顶点,注意判断是否能到达入口处.只需判断直线是否与每个横切面的直线都有相交. #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using

Pipe - POJ 1039(线段相交交点)

题目大意:有一个不反光并且不透光的管道,现在有一束光线从最左端进入,问能达到的最右端是多少,输出x坐标. 分析:刚开始做是直接枚举两个点然后和管道进行相交查询,不过这样做需要考虑的太多,细节不容易掌控.后来发现其实只需要对接口进行一下相交查询就简单多了,因为只需要考虑能不能通过每个截口就可以了,而且这样做的好处还有没有平行线和重叠线的情况,因为所有的截口都是垂直于x轴的,换一种想法海阔太空啊. 代码如下: =============================================

POJ 1039 直线和线段相交

题意: 题意很好理解,从左边射过来的光线,最远能经过管道到右边多少距离. 分析: 光线一定经过一个上端点和一个下端点,这一点很容易想到.然后枚举上下端点即可 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #define eps 1e-8 #define INF 1e9 #define OK sgn(tmp

POJ 1039问题描述

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 co