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

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.

2

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

 
 
 
 
总共4*n+1个点个点。
根据线段交去判断会不会冲突,可以直接连的就建立一条路径。
 
然后求最短路。
因为点很小,所以无论哪种最短路算法都可使用。
 
 
/************************************************************
* Author : kuangbin
* Email : kuangbin2009@126.com
* Last modified : 2013-07-14 10:47
* Filename : POJ1556TheDoors.cpp
* Description :
* *********************************************************/ #include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
#include <map>
#include <vector>
#include <set>
#include <string>
#include <math.h> using namespace std; const double eps = 1e-;
int sgn(double x)
{
if(fabs(x) < eps)return ;
if(x < ) return -;
else return ;
}
struct Point
{
double x,y;
Point(){}
Point(double _x,double _y)
{
x = _x;y = _y;
}
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;
}
};
struct Line
{
Point s,e;
Line(){}
Line(Point _s,Point _e)
{
s = _s;e = _e;
}
};
//判断线段相交
bool inter(Line l1,Line l2)
{
return
max(l1.s.x,l1.e.x) >= min(l2.s.x,l2.e.x) &&
max(l2.s.x,l2.e.x) >= min(l1.s.x,l1.e.x) &&
max(l1.s.y,l1.e.y) >= min(l2.s.y,l2.e.y) &&
max(l2.s.y,l2.e.y) >= min(l1.s.y,l1.e.y) &&
sgn((l2.s-l1.s)^(l1.e-l1.s))*sgn((l2.e-l1.s)^(l1.e-l1.s)) <= &&
sgn((l1.s-l2.s)^(l2.e-l2.s))*sgn((l1.e-l2.s)^(l2.e-l2.s)) <= ;
}
double dist(Point a,Point b)
{
return sqrt((b-a)*(b-a));
}
const int MAXN = ;
Line line[MAXN];
double dis[MAXN][MAXN];
const double INF = 1e20;
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n;
double x,y1,y2,y3,y4;
while(scanf("%d",&n) == )
{
if(n == -) break;
for(int i = ;i <= n;i++)
{
scanf("%lf%lf%lf%lf%lf",&x,&y1,&y2,&y3,&y4);
line[*i-] = Line(Point(x,y1),Point(x,y2));
line[*i] = Line(Point(x,y3),Point(x,y4));
}
for(int i = ;i <= *n+;i++)
for(int j = ;j <= *n+;j++)
{
if(i == j)dis[i][j] = ;
else dis[i][j] = INF;
}
for(int i = ;i <= *n;i++)
{
int lid = (i+)/;
bool flag = true;
Point tmp;
if(i&)tmp = line[(i+)/].s;
else tmp = line[(i+)/].e;
for(int j = ;j < lid;j++)
if(inter(line[*j-],Line(Point(,),tmp)) == false
&& inter(line[*j],Line(Point(,),tmp)) == false)
flag = false;
if(flag)dis[][i] =dis[i][] = dist(Point(,),tmp);
flag = true;
for(int j = lid+;j <= n;j++)
if(inter(line[*j-],Line(Point(,),tmp)) == false
&& inter(line[*j],Line(Point(,),tmp)) == false)
flag = false;
if(flag)dis[i][*n+] =dis[*n+][i] = dist(Point(,),tmp);
}
for(int i = ;i <= *n;i++)
for(int j = i+;j <=*n;j++)
{
int lid1 = (i+)/;
int lid2 = (j+)/;
bool flag = true;
Point p1,p2;
if(i&)p1 = line[(i+)/].s;
else p1 = line[(i+)/].e;
if(j&)p2 = line[(j+)/].s;
else p2 = line[(j+)/].e;
for(int k = lid1+;k < lid2;k++)
if(inter(line[*k-],Line(p1,p2)) == false
&& inter(line[*k],Line(p1,p2)) == false)
flag = false;
if(flag) dis[i][j] = dis[j][i] = dist(p1,p2);
}
bool flag = true;
for(int i = ;i <= n;i++)
if(inter(line[*i-],Line(Point(,),Point(,))) == false
&& inter(line[*i],Line(Point(,),Point(,))) == false)
flag = false;
if(flag)dis[][*n+] = dis[*n+][] = ;
for(int k = ;k <= *n+;k++)
for(int i = ;i <= *n+;i++)
for(int j = ;j <= *n+;j++)
if(dis[i][k] + dis[k][j] < dis[i][j])
dis[i][j] = dis[i][k] + dis[k][j];
printf("%.2lf\n",dis[][*n+]);
} return ;
}
 
 

POJ 1556 The Doors(线段交+最短路)的更多相关文章

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

    #include <iostream> #include <stdio.h> #include <string.h> #include <algorithm& ...

  2. POJ 1556 The Doors 线段交 dijkstra

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

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

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

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

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

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

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

  6. POJ 1556 计算几何 判断线段相交 最短路

    题意: 在一个左下角坐标为(0,0),右上角坐标为(10,10)的矩形内,起点为(0,5),终点为(10,5),中间会有许多扇垂直于x轴的门,求从起点到终点在能走的情况下的最短距离. 分析: 既然是求 ...

  7. POJ 3304 Segments 基础线段交判断

    LINK 题意:询问是否存在直线,使得所有线段在其上的投影拥有公共点 思路:如果投影拥有公共区域,那么从投影的公共区域作垂线,显然能够与所有线段相交,那么题目转换为询问是否存在直线与所有线段相交.判断 ...

  8. POJ 1556 The Doors【最短路+线段相交】

    思路:暴力判断每个点连成的线段是否被墙挡住,构建图.求最短路. 思路很简单,但是实现比较复杂,模版一定要可靠. #include<stdio.h> #include<string.h ...

  9. 简单几何(线段相交+最短路) POJ 1556 The Doors

    题目传送门 题意:从(0, 5)走到(10, 5),中间有一些门,走的路是直线,问最短的距离 分析:关键是建图,可以保存所有的点,两点连通的条件是线段和中间的线段都不相交,建立有向图,然后用Dijks ...

随机推荐

  1. HDU 3544 (不平等博弈) Alice's Game

    切巧克力的游戏,想得还是不是太明白. 后者会尽量选前着切后其中小的一块来切,那么先手须尽量取中间来切. So?题解都是这么一句话,不知道是真懂了还是从别人那抄过来的. 后来找到一个官方题解,分析得比较 ...

  2. UVa 424 Integer Inquiry

    之前杭电上也做过a + b的高精度的题,不过这道题的区别是有多组数据. 之前做的时候开了3个字符数组a,b,c,在计算的时候还要比较a,b长度,短的那个还要加'0',还设置了一个add来存放进位. 现 ...

  3. LA 4794 Sharing Chocolate

    大白书中的题感觉一般都比较难,能理解书上代码就已经很不错了 按照经验,一般数据较小的题目,都有可能是用状态压缩来解决的 题意:问一个面积为x×y的巧克力,能否切若干刀,将其切成n块面积为A1,A2,, ...

  4. 报错:对象必须实现 IConvertible;以分隔符进行分割链接concat_ws的使用方法;mysql数据类型转换cast,convert

    错误故障,mysql  服务器上用 concat_ws 函数,连接了一串数字,最后 服务器返回的字段就变成了一个 byte ,而我们想要的类型是  string 类型,那么转换的时候,就报错了. 正确 ...

  5. 一个小面试题sql

    一.            问答题 1简要说明分页是如何实现的. A:sqlserver: Select top(pagesize)  * from  student where id not in( ...

  6. mysql mac启动

    设置别名 alias mysql=/usr/local/mysql/bin/mysql alias mysqladmin=/usr/local/mysql/bin/mysqladmin 修改密码 su ...

  7. 【解题报告】HDU -1142 A Walk Through the Forest

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1142 题目大意:Jimmy要从办公室走路回家,办公室在森林的一侧,家在另一侧,他每天要采取不一样的路线 ...

  8. acess() 判断目录是否存在

    acess()功能描述: 检查调用进程是否可以对指定的文件执行某种操作. <pre lang="c" escaped="true">#include ...

  9. Excel 之查找与替换

    Excel查找与替换 1,一旦学会查找,替换就简单了. 2,查找下面有一个选项,里面有对查找的范围进行限制 3,你可以选中一个区域,然后再查找,查找只会在你选择的区域里面进行 4,查找只能找特定值,而 ...

  10. Android系统在超级终端下必会的命令大全(adb shell命令大全)

    . 显示系统中全部Android平台: android list targets . 显示系统中全部AVD(模拟器): android list avd . 创建AVD(模拟器): android c ...