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 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.

思路:计算几何。从结果反过来可以证:如果一根光线没有擦到2个顶点,那肯定不是最优的解(可以移动或旋转取到一个更优解)。枚举上下两个顶点成光线所在直线,然后判断光线是否能合法,合法的话求出它射到的最远距离

#include"stdio.h"
#include"string.h"
#include"math.h"
#include"iostream"
#include"algorithm"
using namespace std;
#define LL __int64
#define N 30
const double eps=1e-8;
#define max(a,b) ((a)>(b)?(a):(b))
struct point  //存储点坐标
{
    double x,y;
}up[N],down[N];
double ans;
int n;
double Cross(point a,point b,point c)      //叉积判断点与直线位置关系
{                                          //若点在直线逆时针方向,返回正值
    return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);
}
bool fun(point a,point b,int m)
{
    int i,sign;
    double x1,x2,x3,x4,y1,y2,y3,y4,aa,bb,cc,dd,x;
    for(i=0;i<n;i++)
    {
        if(Cross(a,b,up[i])<-eps)       //管道顶点在直线下方
        {
            sign=1;break;
        }
        if(Cross(a,b,down[i])>eps)      //管道底在直线上方
        {
            sign=2;break;
        }
    }
    if(i==n)
        return true;
    if(i<m)
        return false;
    if(sign==1)      //求两直线交点横坐标
    {
        x1=up[i-1].x;
        y1=up[i-1].y;
        x2=up[i].x;
        y2=up[i].y;
    }
    else
    {
        x1=down[i-1].x;
        y1=down[i-1].y;
        x2=down[i].x;
        y2=down[i].y;
    }
    x3=a.x;y3=a.y;x4=b.x;y4=b.y;
    aa=x2-x1;bb=y2-y1;cc=x4-x3;dd=y4-y3;
    x=((y3-y1)*(aa*cc)+bb*cc*x1-aa*dd*x3)/(bb*cc-aa*dd);
    ans=max(ans,x);
    return false;
}
int main()
{
    int i,j;
    while(scanf("%d",&n),n)
    {
        for(i=0;i<n;i++)
        {
            scanf("%lf%lf",&up[i].x,&up[i].y);
            down[i].x=up[i].x;
            down[i].y=up[i].y-1;
        }
        ans=-1000000;
        bool flag=false;
        for(i=0;i<n&&!flag;i++)
        {
            for(j=i+1;j<n;j++)
            {
                flag=fun(up[i],down[j],j);
                if(flag)
                    break;
                flag=fun(down[i],up[j],j);
                if(flag)
                    break;
            }
        }
        if(flag)
            printf("Through all the pipe.\n");
        else
            printf("%.2f\n",ans);
    }
    return 0;
}
时间: 2024-10-10 17:39:00

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(几何基础)

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 th

简单几何(直线与线段相交) 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

题意:一根管子,中间有一些拐点,给出拐点的上坐标,下坐标为上坐标的纵坐标减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 Transmitters(计算几何 极角排序啊)

题目链接:http://poj.org/problem?id=1106 Description In a wireless network with multiple transmitters sending on the same frequencies, it is often a requirement that signals don't overlap, or at least that they don't conflict. One way of accomplishing thi

POJ 1039 直线和线段相交

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