POJ 1556 The Doors 线段判交+Dijkstra
The Doors
Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 6734 Accepted: 2670 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 7The 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
-1Sample Output
10.00
10.06
题目大意: 给定有多少个墙,每个墙有两个门,问从(0, 5)->(10, 5)这个点的最短距离是多少,不能穿墙而过
解题思路: 既然是求最短路径的,那就转化到最短路径来算. 关键是怎么转化问题. 因为每个门都有可能成为必须要走的路线,而且每个门都有两个端点. 所以只需要枚举每个端点就行了.如果任意两个短线没有墙阻挡,那么就是可以直达的, 就把他加到图中,如果有墙阻隔,那么就是不直接可达.所以图的建立就是遍历所有的端点,包括起始点和终点.
/*************************************************************************
> File Name: poj_1556.cpp
> Author:
> Mail:
> Created Time: 2015年04月02日 星期四 14时55分17秒
************************************************************************/ #include<iostream>
#include <cstdio>
#include <cstring>
#include <math.h>
using namespace std;
const int N = ;
const int INF = ;
struct point{
double x, y;
};
point p[N];
double dis[N];
double Map[N][N];
bool vis[N];
int n;
double getDistance(int i, int j)//得到两个点之间的距离
{
return sqrt((p[i].x - p[j].x) * (p[i].x - p[j].x) + (p[i].y - p[j].y) * (p[i].y - p[j].y));
}
double getDirection(point a, point b, point c)//判断c与直线ab的关系
{
point t1, t2;
t1.x = c.x - a.x; t1.y = c.y - a.y;
t2.x = b.x - a.x; t2.y = b.y - a.y;
return (t1.x * t2.y - t1.y * t2.x);
}
bool segment_intersect(point a, point b, point c, point d)//判断线段是否相交
{
double d1 = getDirection(a, b, c);
double d2 = getDirection(a, b, d);
double d3 = getDirection(c, d, a);
double d4 = getDirection(c, d, b);
if (d1 * d2 < && d3 * d4 < )
return true;
return false;
}
bool isCross(int a, int b)//判断两点之间是否有墙阻隔
{
point t1, t2;
int i;
if (a == )
i = ;
else
i = a / + (a % != ) + ;
for (; i < b / + (b % != ); i++)
{
t1.x = p[ * i - ].x;
t1.y = ;
t2.x = t1.x; t2.y = 10.0;
if (segment_intersect(t1, p[ * i - ], p[a], p[b]) || segment_intersect(p[ * i - ], p[ * i - ], p[a], p[b])
|| segment_intersect(p[ * i], t2, p[a], p[b]))
return true; }
return false;
}
void Dijkstra()//单源最短路径
{
memset(vis, false, sizeof(vis));
int m = * n + ;
for (int i = ; i < m; i++)
dis[i] = Map[][i];
dis[] = ;
vis[] = true;
double min;
int k;
for (int i = ; i < m; i++)
{
min = INF;
for (int j = ; j < m; j++)
{
if (!vis[j] && min > dis[j])
{
k = j;
min = dis[j];
}
}
vis[k] = true;
for (int j = ; j < m; j++)
{
if (!vis[j] && dis[j] > dis[k] + Map[k][j])
dis[j] = dis[k] + Map[k][j];
} }
}
int main()
{
while (~scanf("%d", &n) && n != -)
{
double a, b, c, d, e;
p[].x = ; p[].y = ;
p[ * n + ].x = ; p[ * n + ].y = ;//一共4*n+2个点
for (int i = ; i <= * n; i++)
{
scanf("%lf %lf %lf %lf %lf", &a, &b, &c, &d, &e);
p[i].x = a; p[i].y = b;
p[++i].x = a; p[i].y = c;
p[++i].x = a; p[i].y = d;
p[++i].x = a; p[i].y = e;
}
for (int i = ; i < * n + ; i++)
{
for (int j = ; j < * n + ; j++)
if (i != j)
Map[i][j] = INF;
else
Map[i][j] = ;
}
for (int i = ; i < * n + ; i++)//建立地图
{
for (int j = i + ; j < * n + ; j++)
{
if (!isCross(i, j))
Map[i][j] = getDistance(i, j);
}
}
Dijkstra();//求最短路径
printf("%.2f\n", dis[ * n + ]); } return ;
}
POJ 1556 The Doors 线段判交+Dijkstra的更多相关文章
- POJ 1556 - The Doors 线段相交不含端点
POJ 1556 - The Doors题意: 在 10x10 的空间里有很多垂直的墙,不能穿墙,问你从(0,5) 到 (10,5)的最短距离是多少. 分析: 要么直达,要么 ...
- POJ 1556 The Doors 线段交 dijkstra
LINK 题意:在$10*10$的几何平面内,给出n条垂直x轴的线,且在线上开了两个口,起点为$(0, 5)$,终点为$(10, 5)$,问起点到终点不与其他线段相交的情况下的最小距离. 思路:将每个 ...
- POJ 1556 The Doors(线段交+最短路)
#include <iostream> #include <stdio.h> #include <string.h> #include <algorithm& ...
- (线段判交的一些注意。。。)nyoj 1016-德莱联盟
1016-德莱联盟 内存限制:64MB 时间限制:1000ms 特判: No通过数:9 提交数:9 难度:1 题目描述: 欢迎来到德莱联盟.... 德莱文... 德莱文在逃跑,卡兹克在追.... 我们 ...
- (叉积,线段判交)HDU1086 You can Solve a Geometry Problem too
You can Solve a Geometry Problem too Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/3 ...
- POJ 1556 The Doors(线段交+最短路)
The Doors Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 5210 Accepted: 2124 Descrip ...
- 简单几何(线段相交+最短路) POJ 1556 The Doors
题目传送门 题意:从(0, 5)走到(10, 5),中间有一些门,走的路是直线,问最短的距离 分析:关键是建图,可以保存所有的点,两点连通的条件是线段和中间的线段都不相交,建立有向图,然后用Dijks ...
- POJ 1556 The Doors【最短路+线段相交】
思路:暴力判断每个点连成的线段是否被墙挡住,构建图.求最短路. 思路很简单,但是实现比较复杂,模版一定要可靠. #include<stdio.h> #include<string.h ...
- poj 1556 The Doors(线段相交,最短路)
The Doors Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 7430 Accepted: 2915 Descr ...
随机推荐
- python下 help()使用方法
查看python所有的modules:help("modules") 单看python所有的modules中包含指定字符串的modules: help("modules ...
- 你好,C++(32) 类是对现实世界的抽象和描述 6.2.1 类的声明和定义
6.2 类:当C++爱上面向对象 类这个概念是面向对象思想在C++中的具体体现:它既是封装的结果,同时也是继承和多态的载体.因此,要想学习C++中的面向对象程序设计,也就必须从“类”开始. 6.2. ...
- KB006: CSS 框模型( Box module )
框和布局 在 KB005: CSS 层叠 中已经介绍了 CSS 的重要之处.CSS 可以说是页面表现的基础, CSS 可以控制布局,控制元素的渲染. 布局是讲在电影画面构图中,对环境的布置.人物地位的 ...
- arp断网攻击解决办法
局域网中有这个提示arp断网攻击是正常的,说明防火墙已经拦截了,是有人用P2P工具控制你的网速,或者是局域网有机器中病毒了也会有这样的提示,不过不用担心,今天给大家带来几个防止arp断网攻击的办法,希 ...
- Yii2的相关学习记录,初始化Yii2(二)
前面已经将Yii2下载下来了,那我们就需要能实际的使用. 一.初始化,因为我都是在windows系统下,所以用cmd命令打开下载下来的Yii2的根目录.然后运行下面命令: init 会提示选择0为开发 ...
- iOS开发——OC篇&OC高级语法
iOS开发高级语法之分类,拓展,协议,代码块详解 一:分类 什么是分类Category? 分类就是类的补充和扩展部分 补充和扩展的每个部分就是分类 分类本质上是类的一部分 分类的定义 分类也是以代码的 ...
- ASP.Net string 类的扩展方法 [转]
string 类的扩展方法列表(基本相同于 IEnumerable<T> 接口的成员列表): Aggregate<> //累加 All<> / ...
- jQuery全选、反选、全不选
原文链接:https://yq.aliyun.com/articles/33443 HTML内容部分: <ul id="items"> <li> <l ...
- h.264 Bi-Predictive Motion Search
在做B帧的运动预测时,有两组参考图像列表(refList0, refList1),需要进行分别前向预测.后向预测.传统的预测方式是: 对refList0进行前向预测,得到最佳前向ref与mv. 对re ...
- centos7安装VLC播放器
centos7安装VLC播放器 1.安装eple 下载地址:https://dl.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-5.noar ...