POJ (线段相交 最短路) The Doors
题意:
一个正方形中有n道竖直的墙,每道墙上开两个门。求从左边中点走到右边中点的最短距离。
分析:
以起点终点和每个门的两个端点建图,如果两个点可以直接相连(即不会被墙挡住),则权值为两点间的欧几里得距离。
然后求起点到终点的最短路即可。
- #include <cstdio>
- #include <cmath>
- #include <cstring>
- #include <vector>
- #include <algorithm>
- using namespace std;
- const int maxn = ;
- const double INF = 1e4;
- const double eps = 1e-;
- struct Point
- {
- double x, y;
- Point(double x=, double y=):x(x), y(y) {}
- }p[maxn * ];
- typedef Point Vector;
- Point read_point()
- {
- double x, y;
- scanf("%lf%lf", &x, &y);
- return Point(x, y);
- }
- Point operator - (const Point& A, const Point& B)
- { return Point(A.x-B.x, A.y-B.y); }
- Vector operator / (const Vector& A, double p)
- { return Vector(A.x/p, A.y/p); }
- double Dot(const Vector& A, const Vector& B)
- { return A.x*B.x + A.y*B.y; }
- double Length(const Vector& A)
- { return sqrt(Dot(A, A)); }
- struct Door
- {
- double x, y1, y2, y3, y4;
- Door(double x=, double y1=, double y2=, double y3=, double y4=):x(x), y1(y1), y2(y2), y3(y3), y4(y4) {}
- };
- vector<Door> door;
- double d[maxn * ], w[maxn * ][maxn * ];
- bool vis[maxn * ];
- int cnt;
- bool isOK(int a, int b)
- {//判断两点是否能直接到达
- if(p[a].x >= p[b].x) swap(a, b);
- for(int i = ; i < door.size(); ++i)
- {
- if(door[i].x <= p[a].x) continue;
- if(door[i].x >= p[b].x) break;
- double k = (p[b].y-p[a].y) / (p[b].x-p[a].x);
- double y = p[a].y + k * (door[i].x - p[a].x);
- if(!(y>=door[i].y1&&y<=door[i].y2 || y>=door[i].y3&&y<=door[i].y4)) return false;
- }
- return true;
- }
- void Init()
- {
- for(int i = ; i < cnt; ++i)
- for(int j = i; j < cnt; ++j)
- if(i == j) w[i][j] = ;
- else w[i][j] = w[j][i] = INF;
- }
- int main()
- {
- //freopen("in.txt", "r", stdin);
- int n;
- while(scanf("%d", &n) == && n + )
- {
- door.clear();
- memset(vis, false, sizeof(vis));
- memset(d, , sizeof(d));
- p[] = Point(, );
- cnt = ;
- for(int i = ; i < n; ++i)
- {
- double x, y[];
- scanf("%lf", &x);
- for(int j = ; j < ; ++j) { scanf("%lf", &y[j]); p[cnt++] = Point(x, y[j]); }
- door.push_back(Door(x, y[], y[], y[], y[]));
- }
- p[cnt++] = Point(, );
- Init();
- for(int i = ; i < cnt; ++i)
- for(int j = i+; j < cnt; ++j)
- {
- double l = Length(Vector(p[i]-p[j]));
- if(p[i].x == p[j].x) continue;
- if(isOK(i, j))
- w[i][j] = w[j][i] = l;
- }
- //Dijkstra
- d[] = ;
- for(int i = ; i < cnt; ++i) d[i] = INF;
- for(int i = ; i < cnt; ++i)
- {
- int x;
- double m = INF;
- for(int y = ; y < cnt; ++y) if(!vis[y] && d[y] <= m) m = d[x=y];
- vis[x] = ;
- for(int y = ; y < cnt; ++y) d[y] = min(d[y], d[x] + w[x][y]);
- }
- printf("%.2f\n", d[cnt-]);
- }
- return ;
- }
代码君
POJ (线段相交 最短路) The Doors的更多相关文章
- POJ_1556_The Doors_判断线段相交+最短路
POJ_1556_The Doors_判断线段相交+最短路 Description You are to find the length of the shortest path through a ...
- 简单几何(线段相交+最短路) POJ 1556 The Doors
题目传送门 题意:从(0, 5)走到(10, 5),中间有一些门,走的路是直线,问最短的距离 分析:关键是建图,可以保存所有的点,两点连通的条件是线段和中间的线段都不相交,建立有向图,然后用Dijks ...
- POJ 1556 The Doors(线段相交+最短路)
题目: Description You are to find the length of the shortest path through a chamber containing obstruc ...
- POJ 2556 (判断线段相交 + 最短路)
题目: 传送门 题意:在一个左小角坐标为(0, 0),右上角坐标为(10, 10)的房间里,有 n 堵墙,每堵墙都有两个门.每堵墙的输入方式为 x, y1, y2, y3, y4,x 是墙的横坐标,第 ...
- POJ 1556 计算几何 判断线段相交 最短路
题意: 在一个左下角坐标为(0,0),右上角坐标为(10,10)的矩形内,起点为(0,5),终点为(10,5),中间会有许多扇垂直于x轴的门,求从起点到终点在能走的情况下的最短距离. 分析: 既然是求 ...
- POJ 1556 The Doors【最短路+线段相交】
思路:暴力判断每个点连成的线段是否被墙挡住,构建图.求最短路. 思路很简单,但是实现比较复杂,模版一定要可靠. #include<stdio.h> #include<string.h ...
- POJ 1556 The Doors(线段交+最短路)
The Doors Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 5210 Accepted: 2124 Descrip ...
- POJ 1556 The Doors(线段交+最短路)
#include <iostream> #include <stdio.h> #include <string.h> #include <algorithm& ...
- poj 1066 线段相交
链接:http://poj.org/problem?id=1066 Treasure Hunt Time Limit: 1000MS Memory Limit: 10000K Total Subm ...
随机推荐
- H264学习第一篇(编码结构分析)
学习H264之前,最好阅读一下维基百科中有关H264的相关介绍,里面包含了其的发展历程.主要特点.参考文献.参考网站等. 研究H264的主要文件包括两份参考手册(一份是语法结构参考手册,一份是JM开发 ...
- Android开发中Eclipse里的智能提示设置
今天开始学习一下Android开发,直接在Android Developers下载的一个开发工具包,然后再下了一个JDK,配置完环境变量等一系列的工作后环境就搭建好了,在新建好第一个Android项目 ...
- iOS中为网站添加图标到主屏幕以及增加启动画面
虽然没有能力开发Native App,但还是可以利用iOS中Safari浏览器的特性小小的折腾一下,做一个伪Web App满足下小小的虚荣心的. 既然是在iOS中的Safari折腾的,那么代码中利用到 ...
- Mac技巧之让U盘、移动硬盘在苹果电脑和Windows PC都能识别/读写,且支持4GB大文件:exFAT格式
如果您的 U 盘.移动硬盘既要用于 PC 又要用于苹果电脑,Mac OS X 系统的 HFS+ 和 Windows 的 NTFS 格式显然都不行……HFS+ 在 Windows 下不识别,NTFS 格 ...
- 如何应用CLR线程池来管理多线程
class Program { static void Main(string[] args) { int intWorkerT ...
- WPF系列
一.ListView绑定数据源XML //前端代码 1 <Window x:Class="ListView读取XML数据.MainWindow" xmlns="ht ...
- 【BZOJ3262】 陌上花开
Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量.定义一朵花A比另一朵花B要美丽,当 ...
- Hadoop-2.2.0 + Hbase-0.96.2 + Hive-0.13.1(转)
From:http://www.itnose.net/detail/6065872.html # 需要软件 Hadoop-2.2.0(目前Apache官网最新的Stable版本) Hbase-0.96 ...
- Windows下的Memcache安装与测试教程
Windows下的Memcache安装 1.下载memcache for windows. 下载地址:http://splinedancer.com/memcached-win32/,推荐下载bina ...
- hdu 4648
求一个数列中 去掉一些连续的数之后 不改变对m取余后的值 就是求一个最长的连续子序列 对m取余后为0 我的方法可能比较水 #include<iostream> #include<c ...