The Doors

http://poj.org/problem?id=1556

Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 10466   Accepted: 3891

Description

You are to find the length of the shortest path through a chamber containing obstructing walls. The chamber will always have sides at x = 0, x = 10, y = 0, and y = 10. The initial and final points of the path are always (0, 5) and (10, 5). There will also be from 0 to 18 vertical walls inside the chamber, each with two doorways. The figure below illustrates such a chamber and also shows the path of minimal length. 

Input

The input data for the illustrated chamber would appear as follows.


4 2 7 8 9 
7 3 4.5 6 7

The first line contains the number of interior walls. Then there is a line for each such wall, containing five real numbers. The first number is the x coordinate of the wall (0 < x < 10), and the remaining four are the y coordinates of the ends of the doorways in that wall. The x coordinates of the walls are in increasing order, and within each line the y coordinates are in increasing order. The input file will contain at least one such set of data. The end of the data comes when the number of walls is -1.

Output

The output should contain one line of output for each chamber. The line should contain the minimal path length rounded to two decimal places past the decimal point, and always showing the two decimal places past the decimal point. The line should contain no blanks.

Sample Input

1
5 4 6 7 8
2
4 2 7 8 9
7 3 4.5 6 7
-1

Sample Output

10.00
10.06

Source

有18堵墙!!!因为没看清这个疯狂爆RE

poj上交C++会CE,要自己写hypot函数

double hypot(double x,double y){
return sqrt(x*x+y*y);
}
 #include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std;
const double eps=1e-;
const double INF=1e20;
const double PI=acos(-1.0);
const int maxp=;
int sgn(double x){
if(fabs(x)<eps) return ;
if(x<) return -;
else return ;
}
inline double sqr(double x){return x*x;}
struct Point{
double x,y;
Point(){}
Point(double _x,double _y){
x=_x;
y=_y;
}
void input(){
scanf("%lf %lf",&x,&y);
}
void output(){
printf("%.2f %.2f\n",x,y);
}
bool operator == (const Point &b)const{
return sgn(x-b.x) == && sgn(y-b.y)== ;
}
bool operator < (const Point &b)const{
return sgn(x-b.x)==?sgn(y-b.y)<:x<b.x;
}
Point operator - (const Point &b)const{
return Point(x-b.x,y-b.y);
}
//叉积
double operator ^ (const Point &b)const{
return x*b.y-y*b.x;
}
//点积
double operator * (const Point &b)const{
return x*b.x+y*b.y;
}
//返回长度
double len(){
return hypot(x,y);
}
//返回长度的平方
double len2(){
return x*x+y*y;
}
//返回两点的距离
double distance(Point p){
return hypot(x-p.x,y-p.y);
}
Point operator + (const Point &b)const{
return Point(x+b.x,y+b.y);
}
Point operator * (const double &k)const{
return Point(x*k,y*k);
}
Point operator / (const double &k)const{
return Point(x/k,y/k);
} //计算pa和pb的夹角
//就是求这个点看a,b所成的夹角
///LightOJ1202
double rad(Point a,Point b){
Point p=*this;
return fabs(atan2(fabs((a-p)^(b-p)),(a-p)*(b-p)));
}
//化为长度为r的向量
Point trunc(double r){
double l=len();
if(!sgn(l)) return *this;
r/=l;
return Point(x*r,y*r);
}
//逆时针转90度
Point rotleft(){
return Point(-y,x);
}
//顺时针转90度
Point rotright(){
return Point(y,-x);
}
//绕着p点逆时针旋转angle
Point rotate(Point p,double angle){
Point v=(*this) -p;
double c=cos(angle),s=sin(angle);
return Point(p.x+v.x*c-v.y*s,p.y+v.x*s+v.y*c);
}
}; struct Line{
Point s,e;
Line(){}
Line(Point _s,Point _e){
s=_s;
e=_e;
}
bool operator==(Line v){
return (s==v.s)&&(e==v.e);
}
//根据一个点和倾斜角angle确定直线,0<=angle<pi
Line(Point p,double angle){
s=p;
if(sgn(angle-PI/)==){
e=(s+Point(,));
}
else{
e=(s+Point(,tan(angle)));
}
}
//ax+by+c=0;
Line(double a,double b,double c){
if(sgn(a)==){
s=Point(,-c/b);
e=Point(,-c/b);
}
else if(sgn(b)==){
s=Point(-c/a,);
e=Point(-c/a,);
}
else{
s=Point(,-c/b);
e=Point(,(-c-a)/b);
}
}
void input(){
s.input();
e.input();
}
void adjust(){
if(e<s) swap(s,e);
}
//求线段长度
double length(){
return s.distance(e);
}
//返回直线倾斜角 0<=angle<pi
double angle(){
double k=atan2(e.y-s.y,e.x-s.x);
if(sgn(k)<) k+=PI;
if(sgn(k-PI)==) k-=PI;
return k;
}
//点和直线的关系
//1 在左侧
//2 在右侧
//3 在直线上
int relation(Point p){
int c=sgn((p-s)^(e-s));
if(c<) return ;
else if(c>) return ;
else return ;
}
//点在线段上的判断
bool pointonseg(Point p){
return sgn((p-s)^(e-s))==&&sgn((p-s)*(p-e))<=;
}
//两向量平行(对应直线平行或重合)
bool parallel(Line v){
return sgn((e-s)^(v.e-v.s))==;
}
//两线段相交判断
//2 规范相交
//1 非规范相交
//0 不相交
int segcrossseg(Line v){
int d1=sgn((e-s)^(v.s-s));
int d2=sgn((e-s)^(v.e-s));
int d3=sgn((v.e-v.s)^(s-v.s));
int d4=sgn((v.e-v.s)^(e-v.s));
if((d1^d2)==-&&(d3^d4)==-) return ;
return (d1==&&sgn((v.s-s)*(v.s-e))<=||
d2==&&sgn((v.e-s)*(v.e-e))<=||
d3==&&sgn((s-v.s)*(s-v.e))<=||
d4==&&sgn((e-v.s)*(e-v.e))<=);
}
//直线和线段相交判断
//-*this line -v seg
//2 规范相交
//1 非规范相交
//0 不相交
int linecrossseg(Line v){
int d1=sgn((e-s)^(v.s-s));
int d2=sgn((e-s)^(v.e-s));
if((d1^d2)==-) return ;
return (d1==||d2==);
}
//两直线关系
//0 平行
//1 重合
//2 相交
int linecrossline(Line v){
if((*this).parallel(v))
return v.relation(s)==;
return ;
}
//求两直线的交点
//要保证两直线不平行或重合
Point crosspoint(Line v){
double a1=(v.e-v.s)^(s-v.s);
double a2=(v.e-v.s)^(e-v.s);
return Point((s.x*a2-e.x*a1)/(a2-a1),(s.y*a2-e.y*a1)/(a2-a1));
}
//点到直线的距离
double dispointtoline(Point p){
return fabs((p-s)^(e-s))/length();
}
//点到线段的距离
double dispointtoseg(Point p){
if(sgn((p-s)*(e-s))<||sgn((p-e)*(s-e))<)
return min(p.distance(s),p.distance(e));
return dispointtoline(p);
}
//返回线段到线段的距离
//前提是两线段不相交,相交距离就是0了
double dissegtoseg(Line v){
return min(min(dispointtoseg(v.s),dispointtoseg(v.e)),min(v.dispointtoseg(s),v.dispointtoseg(e)));
}
//返回点P在直线上的投影
Point lineprog(Point p){
return s+(((e-s)*((e-s)*(p-s)))/((e-s).len2()));
}
//返回点P关于直线的对称点
Point symmetrypoint(Point p){
Point q=lineprog(p);
return Point(*q.x-p.x,*q.y-p.y);
}
}; Line L[];
int n; bool Check(Line a,Line b){
if(sgn((a.s-a.e)^(b.s-a.e))*sgn((a.s-a.e)^(b.e-a.e))>) return false;
if(sgn((b.s-b.e)^(a.s-b.e))*sgn((b.s-b.e)^(a.e-b.e))>) return false;
if(sgn(max(a.s.x,a.e.x)-min(b.s.x,b.e.x))>=&&sgn(max(b.s.x,b.e.x)-min(a.s.x,a.e.x))>=
&&sgn(max(a.s.y,a.e.y)-min(b.s.y,b.e.y))>=&&sgn(max(b.s.y,b.e.y)-min(a.s.y,a.e.y))>=)
return true;
else return false;
} double mp[][]; int co; void panduan(Line a,int xx,int yy){
if(a.s.y==||a.s.y==||a.e.y==||a.e.y==) return;
for(int i=;i<co;i++){
if(i!=(xx+)/&&i!=(yy+)/){
if(Check(a,L[i])){
return;
}
}
}
//cout<<xx<<" "<<yy<<" "<<a.length()<<endl; mp[xx][yy]=mp[yy][xx]=a.length();
} int main(){
while(~scanf("%d",&n)){
if(n==-) break;
double x,y1,y2,y3,y4;
co=;
for(int i=;i<;i++){
for(int j=;j<;j++){
mp[i][j]=INF;
}
}
Point s,e;
s.x=,s.y=;
e.x=,e.y=;
//起点为0,终点为co
for(int i=;i<=n;i++){
scanf("%lf %lf %lf %lf %lf",&x,&y1,&y2,&y3,&y4);
L[co].s.x=x,L[co].s.y=,L[co].e.x=x,L[co++].e.y=y1;
L[co].s.x=x,L[co].s.y=y2,L[co].e.x=x,L[co++].e.y=y3;
L[co].s.x=x,L[co].s.y=y4,L[co].e.x=x,L[co++].e.y=;
} Line tmp;
int j;
//不包括起点和终点的建图
for(int i=;i<co;i++){
for(int j=i+;j<co;j++){
tmp.s=L[i].s,tmp.e=L[j].s;
panduan(tmp,(i-)*+,(j-)*+);
tmp.s=L[i].s,tmp.e=L[j].e;
panduan(tmp,(i-)*+,(j-)*+);
tmp.s=L[i].e,tmp.e=L[j].s;
panduan(tmp,(i-)*+,(j-)*+);
tmp.s=L[i].e,tmp.e=L[j].e;
panduan(tmp,(i-)*+,(j-)*+);
}
}
//加上起点和终点
for(int i=;i<co;i++){
tmp.s=s,tmp.e=L[i].s;
panduan(tmp,,(i-)*+);
tmp.s=s,tmp.e=L[i].e;
panduan(tmp,,(i-)*+);
tmp.s=e,tmp.e=L[i].s;
panduan(tmp,(i-)*+,);
tmp.s=e,tmp.e=L[i].e;
panduan(tmp,(i-)*+,);
}
tmp.s=s,tmp.e=e;
panduan(tmp,,);
for(int k=;k<=;k++)
for(int i=;i<=;i++)
for(int j=;j<=;j++)
if(mp[i][j]>mp[i][k]+mp[k][j]+eps)
mp[i][j]=mp[i][k]+mp[k][j];
printf("%.2f\n",mp[][]);
}
return ;
}

The Doors(几何+最短路,好题)的更多相关文章

  1. poj1511/zoj2008 Invitation Cards(最短路模板题)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud Invitation Cards Time Limit: 5 Seconds    ...

  2. HDU 5521.Meeting 最短路模板题

    Meeting Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total ...

  3. hdu-3790最短路刷题

    title: hdu-3790最短路刷题 date: 2018-10-20 14:50:31 tags: acm 刷题 categories: ACM-最短路 概述 一道最短路的水题,,,尽量不看以前 ...

  4. [poj2449]Remmarguts' Date(K短路模板题,A*算法)

    解题关键:k短路模板题,A*算法解决. #include<cstdio> #include<cstring> #include<algorithm> #includ ...

  5. 牛客小白月赛6 I 公交线路 最短路 模板题

    链接:https://www.nowcoder.com/acm/contest/136/I来源:牛客网 题目描述 P市有n个公交站,之间连接着m条道路.P市计划新开设一条公交线路,该线路从城市的东站( ...

  6. POJ 1556 The Doors --几何,最短路

    题意: 给一个正方形,从左边界的中点走到右边界的中点,中间有一些墙,问最短的距离是多少. 解法: 将起点,终点和所有墙的接触到空地的点存下来,然后两两之间如果没有线段(墙)阻隔,就建边,最后跑一个最短 ...

  7. 2018.07.06 POJ1556 The Doors(最短路)

    The Doors Time Limit: 1000MS Memory Limit: 10000K Description You are to find the length of the shor ...

  8. POJ 4046 Sightseeing 枚举+最短路 好题

    有n个节点的m条无向边的图,节点编号为1~n 然后有点权和边权,给出q个询问,每一个询问给出2点u,v 输出u,v的最短距离 这里的最短距离规定为: u到v的路径的所有边权+u到v路径上最大的一个点权 ...

  9. POJ 1556 The Doors(计算几何+最短路)

    这题就是,处理出没两个点.假设能够到达,就连一条边,推断可不能够到达,利用线段相交去推断就可以.最后求个最短路就可以 代码: #include <cstdio> #include < ...

随机推荐

  1. 【转载】CSS + DIV 实现局部布局

    HTML CSS + DIV实现局部布局 1.本章教大家掌握2种布局方式: 1)顶部导航菜单布局,效果图: 2)购物版块布局,效果图: 2.技术目标:使用div + ul-li实现导航菜单布局    ...

  2. 【基础知识五】神经网络NN

    常用模型:BP神经网络,RBF神经网络 一.神经元模型 |  连接权,阈值,激活函数 1. 输入信号通过带权重的连接(connection)进行传递,神经元接收到的总输入值将与神经元的阈值进行比较, ...

  3. win10安装.net framework3.5

    win10默认没有安装.net framework3.5,一般方法需提取Windows安装镜像,麻烦. 离线安装方法如下: cab格式.NET Framework 3.5离线安装包下载地址:百度网盘 ...

  4. Hive环境的安装部署(完美安装)(集群内或集群外都适用)(含卸载自带mysql安装指定版本)

    Hive环境的安装部署(完美安装)(集群内或集群外都适用)(含卸载自带mysql安装指定版本) Hive 安装依赖 Hadoop 的集群,它是运行在 Hadoop 的基础上. 所以在安装 Hive 之 ...

  5. JS 传各种文件到后端

    由于要写一个前端上传文件按钮功能,本人前端是小白,所以在网上搜索了许多,发现FileReader非常好用. 不多BB,直接来. 1,前端只需要一个input标签, <input type=&qu ...

  6. Windows下OpenCV 3.1.0 在 Qt Creator 4.0.2 (Qt 5.7.0 MinGW) 中的开发环境配置

    2017-2-23 Update: 修改并添加了部分细节 最近正在学习OpenCV ,为毕业设计做准备.Windows版本的OpenCV都默认提供对VS的支持,其在VS中的配置比较简单,网上也有大批教 ...

  7. 框架之Tornado(简单介绍)

    引言 回想Django的部署方式 以Django为代表的python web应用部署时采用wsgi协议与服务器对接(被服务器托管),而这类服务器通常都是基于多线程的,也就是说每一个网络请求服务器都会有 ...

  8. centos启用root账号登陆telnet

    1,shutdown iptables或是放行23端口 2,shutdown selinux或是设置放行; 3,yum -y install telnet telnet-server 4,vim /e ...

  9. vue pm2守护进程

    Linux 创建一个.sh可执行脚本,例如hexo.sh 代码 12 #!/usr/bin/env bashhexo server 使用pm2 start hexo.sh执行脚本 Windows 创建 ...

  10. 获取ASPxGridView 中的数据(仅仅是获取;注意模板是如何获取的)

    1.取得控件值 using System.Collections.Generic; //取得当前控件值的集合 直接寻找控件的ID List<object> keyValues = this ...