题意:给定n堵墙,现在要你从(0,5)走去(10,5)的最短距离

思路:刚开始还想模拟,就是从(0,5)走,每次x向右一格,然后判断有没和线段相交就可以。但是它的们有可能是小数形式给出的,这样就GG了(x--x+1中可能存在很多门)。正确的方法应该是建图,对于所有门,他们都有端点的,先把他们加入到图中,包括起点的话,一共有num个点吧。然后暴力判断e[i][j]是否能到达就可以,这里用线段相交就可以判断。然后floyd一下就好。bug点:门的端点不应该加进来,就是(x,0)、(x,10)这样的点不应该加入图中,因为那个是死角,不能出去了。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL; #include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
const double eps = 1e-;
const int maxn = +;
bool same (double a,double b)
{
return fabs(a-b)<eps;
}
struct coor
{
double x,y;
coor(){}
coor(double xx,double yy):x(xx),y(yy){}
double operator ^(coor rhs) const //计算叉积(向量积)
{
return x*rhs.y - y*rhs.x;
}
coor operator -(coor rhs) const //坐标相减,a-b得到向量ba
{
return coor(x-rhs.x,y-rhs.y);
}
double operator *(coor rhs) const //数量积
{
return x*rhs.x + y*rhs.y;
}
bool operator ==(coor rhs) const
{
return same(x,rhs.x)&&(y,rhs.y);//same的定义其实就是和eps比较
}
}a[maxn]; struct Line
{
coor point1,point2;
Line(){}
Line(coor xx,coor yy):point1(xx),point2(yy){}
bool operator &(Line rhs) const //判断直线和rhs线段是否相交
{
//自己表示一条直线,然而rhs表示的是线段
//思路,判断rhs线段上两个端点是否在this直线的同一侧即可,用一侧,就不相交
coor ff1 = point2 - point1; //直线的方向向量
return ( ((rhs.point1-point1)^ff1) * ((rhs.point2-point1)^ff1) ) <= ;//符号不同或者有0,证明相交
}
}LINE[maxn]; bool OnSegment (coor a,coor b,coor c) //判断点C是否在线段ab上
{
double min_x = min(a.x,b.x), min_y = min(a.y,b.y);
double max_x = max(a.x,b.x), max_y = max(a.y,b.y);
if (c.x>=min_x && c.x<=max_x && c.y>=min_y && c.y<=max_y) return true;
else return false;
}
bool SegmentIntersect (coor a,coor b,coor c,coor d)
{
double d1 = (b-a)^(d-a); //direction(a,b,d);以a为起点,计算ab和ab的叉积
double d2 = (b-a)^(c-a);
double d3 = (d-c)^(a-c);
double d4 = (d-c)^(b-c);
if (d1*d2< && d3*d4<) return true;
else if (d1 == && OnSegment(a,b,d)) return true;
else if (d2 == && OnSegment(a,b,c)) return true;
else if (d3 == && OnSegment(c,d,a)) return true;
else if (d4 == && OnSegment(c,d,b)) return true;
else return false;
} int n;
int all=;
double dis (coor a,coor b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double e[maxn][maxn];
void work ()
{
all = ;
int num=;
for (int i=;i<=n;++i)
{
double aa,bb,cc,dd,ee;
scanf("%lf%lf%lf%lf%lf",&aa,&bb,&cc,&dd,&ee);
++all;
LINE[all].point1 = coor(aa,); //a[++num]=coor(aa,0);
LINE[all].point2 = coor(aa,bb);a[++num]=coor(aa,bb); ++all;
LINE[all].point1 = coor(aa,cc);a[++num]=coor(aa,cc);
LINE[all].point2 = coor(aa,dd);a[++num]=coor(aa,dd); ++all;
LINE[all].point1 = coor(aa,ee);a[++num]=coor(aa,ee);
LINE[all].point2 = coor(aa,);//a[++num]=coor(aa,10);
}
a[++num]=coor(,);
a[++num]=coor(,);
//memset(e,0x3f,sizeof e);
for (int i=;i<=maxn-;++i)
{
for (int j=;j<=maxn-;++j)
{
e[i][j]=100000000.0;
} }
for (int i=;i<=num;++i)
{
for (int j=i+;j<=num;++j)
{
int k;
//if (same(a[j].y,0)||same(a[j].y,10)||same(a[i].y,0)||same(a[i].y,10)) continue;
for (k=;k<=all;++k)
{
if (LINE[k].point1==a[i]||LINE[k].point1==a[j]||LINE[k].point2==a[i]||LINE[k].point2==a[j]) continue;
if (SegmentIntersect(a[i],a[j],LINE[k].point1,LINE[k].point2)) break;
}
if (k==all+) e[i][j]=e[j][i]=dis(a[i],a[j]);
}
}
for (int i=;i<=num;++i)
{
for (int j=;j<=num;j++)
{
for (int k=;k<=num;++k)
{
if (e[j][k]>e[j][i]+e[i][k]) e[j][k]=e[j][i]+e[i][k];
}
}
}
printf ("%0.2f\n",e[num-][num]);
//printf ("%0.2f\n",e[num-1][1]);
return;
} int main()
{
#ifdef local
freopen("data.txt","r",stdin);
#endif
while(scanf("%d",&n)!=EOF && n!=-) work();
return ;
}

POJ 1556 E - The Doors的更多相关文章

  1. 【POJ 1556】The Doors 判断线段相交+SPFA

    黑书上的一道例题:如果走最短路则会碰到点,除非中间没有障碍. 这样把能一步走到的点两两连边,然后跑SPFA即可. #include<cmath> #include<cstdio> ...

  2. POJ 1556 - The Doors 线段相交不含端点

    POJ 1556 - The Doors题意:    在 10x10 的空间里有很多垂直的墙,不能穿墙,问你从(0,5) 到 (10,5)的最短距离是多少.    分析:        要么直达,要么 ...

  3. POJ 1556 The Doors 线段交 dijkstra

    LINK 题意:在$10*10$的几何平面内,给出n条垂直x轴的线,且在线上开了两个口,起点为$(0, 5)$,终点为$(10, 5)$,问起点到终点不与其他线段相交的情况下的最小距离. 思路:将每个 ...

  4. 最短路+线段交 POJ 1556 好题

    // 最短路+线段交 POJ 1556 好题 // 题意:从(0,5)到(10,5)的最短距离,中间有n堵墙,每堵上有两扇门可以通过 // 思路:先存图.直接n^2来暴力,不好写.分成三部分,起点 终 ...

  5. POJ 1556 - The Doors - [平面几何+建图spfa最短路]

    题目链接:http://poj.org/problem?id=1556 Time Limit: 1000MS Memory Limit: 10000K Description You are to f ...

  6. poj 1556 The Doors

    The Doors Time Limit: 1000 MS Memory Limit: 10000 KB 64-bit integer IO format: %I64d , %I64u   Java ...

  7. POJ 1556 The Doors(线段交+最短路)

    The Doors Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 5210   Accepted: 2124 Descrip ...

  8. poj 1556 The Doors(线段相交,最短路)

      The Doors Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7430   Accepted: 2915 Descr ...

  9. POJ 1556 The Doors 线段判交+Dijkstra

    The Doors Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 6734   Accepted: 2670 Descrip ...

随机推荐

  1. canvas变换(移动,缩放等)

    代码: 1 /** 2 * Created by Administrator on 2016/1/30. 3 */ 4 function draw (id){ 5 var canvas = docum ...

  2. ES6学习之数值扩展

    二进制和八进制表示法(二进制用前缀0b(或0B)表示,八进制用前缀0o(或0O)表示) Number('0b111') Number('0o10') Number.isFinite()(判断一个值是否 ...

  3. VIewPage+Fragment

    效果图: 代码 public class NewOrderListFargmentActivity extends BaseActivity implements OnClickListener { ...

  4. [51nod1058]求N!的长度

    法1:stirling公式近似 $n! \approx \sqrt {2\pi n} {(\frac{n}{e})^n}$ (如果怕n不够大下式不成立,可以当数小于10000时用for求阶层) 也可以 ...

  5. css中的定位属性position(转)

    css中的定位属性position   同样的也是上课的时候发现学生难以理解的一些问题拿出来记录一下,希望帮助初学者. 在css中定位属性position的运用在页面中是很常用的,特别是一些结合js来 ...

  6. lyui 列表 上传

    1.js layui.use(['table', 'element', 'laydate', 'layer','upload'], function () { var table = layui.ta ...

  7. Hadoop-2.3.0-cdh5.0.1完全分布式环境搭建(NameNode,ResourceManager HA)

    编写不易,转载请注明(http://shihlei.iteye.com/blog/2084711)! 说明 本文搭建Hadoop CDH5.0.1 分布式系统,包括NameNode ,Resource ...

  8. windows 服务器安装python及其基本库

    步骤如下: 一.安装python软件: 1.进入windows服务器,从网址下载 python-3.5.4-amd64软件 到桌面: 2.在软件点右键,再“”以管理员身份运行“”,输入管理员密码: 3 ...

  9. p2023&bzoj1798 维护序列

    传送门(洛谷) 传送门(bzoj) 题目 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中的一段数全 ...

  10. JS中apply和call的用法

    JavaScript中有一个call和apply方法,其作用基本相同,但也有略微的区别. 先来看看JS手册中对call的解释: call 方法调用一个对象的一个方法,以另一个对象替换当前对象. cal ...