UVA_303_Pipe_(计算几何基础)
描述
一个管道,有n个拐点(包括起点),给出每个拐点的上面的坐标,下面的横坐标与上面相同,总坐标-1.一道光线从起点口射入,问最多射到x=?的位置碰壁.
303 - Pipe
Time limit: 3.000 seconds
| 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
, where
. 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
there is a corresponding bottom point
(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
and
(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
on separate line. Each of the next n lines contains a pair of real values
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
, 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.
分析
抄黑书:
1.如果某一道光没有擦过顶点,可以平移使解更优(碰到一个顶点).
2.如果某一道光只擦过一个顶点,可以旋转使解更优(碰到另一个顶点).
3.如果某一道光没有碰到上下各一个顶点,则可以绕前面或后面的点旋转,使解更优(碰到上下各一个顶点).
4.如果某一道光碰到了上下各一个顶点,则只有一个方向可以旋转,如果向该方向旋转可以使解更优,则旋转,直到再次碰到两个点.这两个点或者一上一下或者在同一方向,继续重复上述过程,直到第4步唯一能够旋转的方向不能使得解更优.
如此一来解法就明了了:因为最终的最优解一定是一上一下两个顶点的连线,所以枚举一上一下的点对,求每条直线的最优解即可.
注意:
1.无论是否时规范相交都要算交点,因为可能是撞在了拐点处,不规范相交的唯一交点求法相同(稍微推到一下就好了).
2.如果光线每通过i,在i-1的边找的时候即要找上面的也要找下面的,因为可能是擦过了上面,撞在了下面,或者擦过了下面,撞在了上面.
#include <bits/stdc++.h>
using namespace std; const int maxn=+;
const double eps=1e-;
int n;
double ans; struct Point{
double x,y;
Point(double x=,double y=):x(x),y(y){}
}up[maxn],down[maxn];
typedef Point Vector;
Vector operator - (Vector a,Vector b){ return Vector(a.x-b.x,a.y-b.y); }
inline int dcmp(double x){
if(fabs(x)<eps) return ;
return x>?:-;
}
inline double cross(Point a,Point b){
return a.x*b.y-b.x*a.y;
}
inline bool segment_cross(Point a,Point b,Point c,Point d,Point &p){
double s1,s2;
int d1,d2;
d1=dcmp(s1=cross(b-a,c-a)),d2=dcmp(s2=cross(b-a,d-a));
if(d1*d2>) return false;
else
p=Point((c.x*s2-d.x*s1)/(s2-s1),(c.y*s2-d.y*s1)/(s2-s1));//无论是否是规范相交,都要算交点
return true;
}
void ray(Point a,Point b){
Point c;
if(!segment_cross(a,b,up[],down[],c)) return;
for(int i=;i<=n;i++){
if(!segment_cross(a,b,up[i],down[i],c)){//如果通过了拐口i,那么一定和up[i],down[i]所连直线相交
segment_cross(a,b,up[i-],up[i],c);//如果没有通过,就在前一条的上面和下面找交点
ans=max(ans,c.x);
segment_cross(a,b,down[i-],down[i],c);
ans=max(ans,c.x);
return;
}
}
ans=up[n].x;
}
void solve(){
ans=up[].x;
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)//枚举每个一上一下的点对
if(i!=j) ray(up[i],down[j]);
if(ans==up[n].x) puts("Through all the pipe.");
else printf("%.2lf\n",ans);
}
int main(){
while(scanf("%d",&n)&&n){
for(int i=;i<=n;i++){
scanf("%lf%lf",&up[i].x,&up[i].y);
down[i].x=up[i].x; down[i].y=up[i].y-;
}
solve();
}
return ;
}
UVA_303_Pipe_(计算几何基础)的更多相关文章
- nyis oj 68 三点顺序 (计算几何基础)
三点顺序 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描写叙述 如今给你不共线的三个点A,B,C的坐标,它们一定能组成一个三角形,如今让你推断A,B,C是顺时针给出的还是逆 ...
- 【BZOJ】1043: [HAOI2008]下落的圆盘(计算几何基础+贪心)
http://www.lydsy.com/JudgeOnline/problem.php?id=1043 唯一让我不会的就是怎么求圆的周长并QAAQ... 然后发现好神!我们可以将圆弧变成$[0, 2 ...
- 计算几何基础——矢量和叉积 && 叉积、线段相交判断、凸包(转载)
转载自 http://blog.csdn.net/william001zs/article/details/6213485 矢量 如果一条线段的端点是有次序之分的话,那么这种线段就称为 有向线段,如果 ...
- BZOJ_1610_[Usaco2008_Feb]_Line连线游戏_(计算几何基础+暴力)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1610 给出n个点,问两两确定的直线中,斜率不同的共有多少条. 分析 暴力枚举直线,算出来斜率放 ...
- 二维计算几何基础题目泛做(SYX第一轮)
题目1: POJ 2318 TOYS 题目大意: 给一个有n个挡板的盒子,从左到右空格编号为0...n.有好多玩具,问每个玩具在哪个空格里面. 算法讨论: 直接叉积判断就可以.注意在盒子的边界上面也算 ...
- 计算几何基础算法几何C++实现
This file is implementation of Common Common Computational Geometry Algorithms.Please please pay att ...
- 【POJ】1556 The Doors(计算几何基础+spfa)
http://poj.org/problem?id=1556 首先路径的每条线段一定是端点之间的连线.证明?这是个坑...反正我是随便画了一下图然后就写了.. 然后re是什么节奏?我记得我开够了啊.. ...
- 【POJ】2318 TOYS(计算几何基础+暴力)
http://poj.org/problem?id=2318 第一次完全是$O(n^2)$的暴力为什么被卡了-QAQ(一定是常数太大了...) 后来排序了下点然后单调搞了搞..(然而还是可以随便造出让 ...
- 【POJ】2653 Pick-up sticks(计算几何基础+暴力)
http://poj.org/problem?id=2653 我很好奇为什么这样$O(n^2)$的暴力能过.... 虽然说这是加了链表优化的,但是最坏不也是$O(n^2)$吗...(只能说数据太弱.. ...
随机推荐
- swift 泛型
T就是类型,范型
- Ibatis中sqlmap参数map中还需要套list的情况如何写?
原始需求: 有若干个参数,需要作为ibatis拼装sql的参数传入,但是有个参数的值比较特殊,是若干种枚举值.具体到这个case,就是有有限个namespace.我每次需要通过传入多个namespac ...
- DbUtil组件及C3P0数据库连接池组件的使用
DbUtils 是 Apache 组织提供的一个开源 JDBC工具类库,它是对JDBC的简单封装,学习成本极低,并且使用dbutils能极大简化jdbc编码的工作量,同时也不会影响程序的性能. 使用c ...
- OpenJudge 2790 迷宫
1.链接地址: http://bailian.openjudge.cn/practice/2790/ 2.题目: 总时间限制: 3000ms 内存限制: 65536kB 描述 一天Extense在森林 ...
- extern “C”的作用
1.引言 C++语言的创建初衷是“a better C”,但是这并不意味着C++中类似C语言的全局变量和函数所采用的编译和连接方式与C语言完全相同.作为一种欲与C兼容的语言,C++保留了一部分过程 式 ...
- compass sprite
1.compass init 初始化一个compass项目,并创建一个images文件夹用来存放合成的sprite图 2.将切好的小图放到images文件夹中 3.在sass文件夹中新建一个test. ...
- .net生成随机验证码图片
/// <summary> /// 自定义图片验证码函数 /// 该函数将生成一个图片验证码,并将生成的code存放于Session["VerifyCode"]变量内. ...
- ubuntu 下的 ftp (gftp)
功能和 windows 下的 ftp 一样 gftp安装方法apt-get install gftp启动方法:gfpt
- PHP curl 采集内容之规则 1
<?phpheader("Content-type:text/html; charset=utf-8");$pattern = '/xxx(.*)yyyy/isU'; //i ...
- 学一点 mysql 双机异地热备份----快速理解mysql主从,主主备份原理及实践
双机热备的概念简单说一下,就是要保持两个数据库的状态 自动同步.对任何一个数据库的操作都自动应用到另外一个数据库,始终保持两个数据库数据一致. 这样做的好处多. 1. 可以做灾备,其中一个坏了可以切换 ...