POJ-1556 The Doors---线段相交+最短路
题目链接:
https://vjudge.net/problem/POJ-1556
题目大意:
给一个10*10的正方形房间中间用墙隔开每个墙上有两个门,给出门的两个端点坐标求从左边中点走到右边中点所需要的最短路程。
思路:
每扇门4个点,只要求出每两点之间的距离就可以建图求最短路径了,但是关键在于如何判断两点之间有没有直接路径,即两点之间呢能否直接连接,这就需要判断线段之间的相交问题,每堵墙有两个门,这堵墙被分成三部分,再判断两点之间有没有直接的路的时候,需要判断两点之间有没有和墙壁相交
比如上面的例子,第一堵墙分成了三部分,分别是:
(4,0)-(4,2)
(4,7)-(4,8)
(4,9)-(4,10)
判断两个点和墙的每一部分的是否相交时候,需要判断墙的两个端点是否在判断的那两个点的线段的同一侧。具体实现看代码,以后整理出计算几何入门必备模板。
- #include<iostream>
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- #include<cmath>
- #include<queue>
- #include<stack>
- #include<map>
- #include<set>
- #include<sstream>
- using namespace std;
- typedef long long ll;
- const int maxn = 1e2 + ;
- const int INF = 1e9 + ;
- int T, n, m, cases;
- struct Point
- {
- double x, y;
- Point(double x, double y):x(x), y(y){}
- Point(){}
- };
- struct Wall
- {
- double x, y[];
- };
- Point p[maxn];//存储每个点
- Wall w[];//存储每堵墙,墙的x升序,y升序
- double Map[maxn][maxn];//邻接矩阵
- double Dis(Point a, Point b)//求两点之间的距离
- {
- return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
- }
- //判断点c位于直线ab上方还是下方
- //矢量AB叉乘AC,大于0说明C在AB上方,小于0C在AB下方
- //(b.x-a.x, b.y-a.y)叉乘(c.x-a.x, c.y-a.y)
- double Judge_Cross(Point a, Point b, Point c)
- {
- return (b.x - a.x) * (c.y - a.y) - (c.x - a.x) * (b.y - a.y);
- }
- bool Isok(Point a, Point b)//判断点a, b是否有直接的路
- {
- if(a.x >= b.x)return false;
- int i = , flag = true;
- while(w[i].x <= a.x && i < n)i++;//排除x坐标比a小的墙
- while(w[i].x < b.x && i < n)
- {
- if(Judge_Cross(a, b, Point(w[i].x, )) * Judge_Cross(a, b, Point(w[i].x, w[i].y[])) < )//点a,b被第一段阻挡
- {
- flag = false;
- break;
- }
- if(Judge_Cross(a, b, Point(w[i].x, w[i].y[])) * Judge_Cross(a, b, Point(w[i].x, w[i].y[])) < )
- {
- flag = false;
- break;
- }
- if(Judge_Cross(a, b, Point(w[i].x, w[i].y[])) * Judge_Cross(a, b, Point(w[i].x, )) < )
- {
- flag = false;
- break;
- }
- i++;
- }
- return flag;
- }
- int tot;
- double dijkstra(int u, int v)
- {
- int vis[maxn];
- double d[maxn];
- memset(vis, , sizeof(vis));
- for(int i = ; i < tot; i++)d[i] = INF * 1.0;
- d[u] = ;
- for(int i = ; i < tot; i++)
- {
- int x;
- double m = 1.0 * INF;
- for(int i = ; i < tot; i++)if(!vis[i] && m > d[i])m = d[x = i];
- vis[x] = ;
- for(int i = ; i < tot; i++)d[i] = min(d[i], d[x] + Map[x][i]);
- }
- return d[v];
- }
- int main()
- {
- while(cin >> n && (n != -))
- {
- p[] = Point(, );
- tot = ;
- for(int i = ; i < n; i++)
- {
- cin >> w[i].x;
- for(int j = ; j < ; j++)
- {
- cin >> w[i].y[j];
- p[tot++] = Point(w[i].x, w[i].y[j]);
- }
- }
- p[tot++] = Point(, );
- for(int i = ; i < tot; i++)//初始化邻接矩阵
- {
- for(int j = ; j < tot; j++)
- Map[i][j] = 1.0 * INF;
- }
- //for(int i = 0; i < tot; i++)cout<<p[i].x<<" "<<p[i].y<<endl;
- for(int i = ; i < tot; i++)//建图
- {
- for(int j = i + ; j < tot; j++)
- {
- if(Isok(p[i], p[j]))//点i和点j有直接的路就建图
- {
- Map[i][j] = Dis(p[i], p[j]);
- //cout<<i<<" "<<j<<" "<<Map[i][j]<<endl;
- }
- }
- }
- printf("%.2f\n", dijkstra(, tot - ));
- }
- return ;
- }
POJ-1556 The Doors---线段相交+最短路的更多相关文章
- POJ 1556 - The Doors 线段相交不含端点
POJ 1556 - The Doors题意: 在 10x10 的空间里有很多垂直的墙,不能穿墙,问你从(0,5) 到 (10,5)的最短距离是多少. 分析: 要么直达,要么 ...
- POJ 1556 The Doors(线段交+最短路)
#include <iostream> #include <stdio.h> #include <string.h> #include <algorithm& ...
- POJ 1556 计算几何 判断线段相交 最短路
题意: 在一个左下角坐标为(0,0),右上角坐标为(10,10)的矩形内,起点为(0,5),终点为(10,5),中间会有许多扇垂直于x轴的门,求从起点到终点在能走的情况下的最短距离. 分析: 既然是求 ...
- POJ 1556 The Doors 线段交 dijkstra
LINK 题意:在$10*10$的几何平面内,给出n条垂直x轴的线,且在线上开了两个口,起点为$(0, 5)$,终点为$(10, 5)$,问起点到终点不与其他线段相交的情况下的最小距离. 思路:将每个 ...
- POJ 1556 The Doors 线段判交+Dijkstra
The Doors Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 6734 Accepted: 2670 Descrip ...
- POJ 2556 (判断线段相交 + 最短路)
题目: 传送门 题意:在一个左小角坐标为(0, 0),右上角坐标为(10, 10)的房间里,有 n 堵墙,每堵墙都有两个门.每堵墙的输入方式为 x, y1, y2, y3, y4,x 是墙的横坐标,第 ...
- POJ 1556 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【最短路+线段相交】
思路:暴力判断每个点连成的线段是否被墙挡住,构建图.求最短路. 思路很简单,但是实现比较复杂,模版一定要可靠. #include<stdio.h> #include<string.h ...
- 简单几何(线段相交+最短路) POJ 1556 The Doors
题目传送门 题意:从(0, 5)走到(10, 5),中间有一些门,走的路是直线,问最短的距离 分析:关键是建图,可以保存所有的点,两点连通的条件是线段和中间的线段都不相交,建立有向图,然后用Dijks ...
随机推荐
- Java内存区域之程序计数器--《深入理解Java虚拟机》学习笔记及个人理解(一)
Java虚拟机程序计数器 在书上的P39页 程序计数器干嘛的? 有了它,字节码解释器才可以知道下一条要执行的字节码指令是哪个. 无论是取下一条指令还是分支.循环.跳转.中断.线程恢复,都需要这个程序计 ...
- 详解小白利用eclipse+CDT+MinGW搭建C++开发环境
安装JDK.安装Eclipse 2.打开Eclipse 找到“help”下的“Eclipse marketplace” 如图: 3.选择相应的C插件: 因为安装过所以显示installe ...
- Docker(四):Docker 三剑客之 Docker Compose
前两篇文章我们介绍了 Dockerfile 的使用Docker(二):Dockerfile 使用介绍,我们知道使用一个 Dockerfile 模板文件可以定义一个单独的应用容器,如果需要定义多个容器就 ...
- Spring boot 应用打包部署
1.Spring Boot内置web spring Boot 其默认是集成web容器的,启动方式由像普通Java程序一样,main函数入口启动.其内置Tomcat容器或Jetty容器,具体由配置来决定 ...
- newInstance()和new()的区别
转载:http://www.jobui.com/mianshiti/it/java/7148/ newInstance: 弱类型.低效率.只能调用无参构造.new: 强类型.相对高效.能调用任何pub ...
- 大数据 --> Spark和Hadoop作业之间的区别
Spark和Hadoop作业之间的区别 熟悉Hadoop的人应该都知道,用户先编写好一个程序,我们称为Mapreduce程序,一个Mapreduce程序就是一个Job,而一个Job里面可以有一个或多个 ...
- Algorithm --> 矩阵链乘法
动态规划--矩阵链乘法 1.矩阵乘法 Note:只有当矩阵A的列数与矩阵B的行数相等时A×B才有意义.一个m×r的矩阵A左乘一个r×n的矩阵B,会得到一个m×n的矩阵C. #include ...
- selenium2自动化测试学习笔记(一)
从这周开始学习自动化测试,采用selenium2,目标是在本月学习到appium,并测试公司的真实APP项目. 系统环境:win10 语言:python3.6.4 工具:selenium2 IDE:p ...
- 指令-arContentedit-可编辑的高度自适应的div
<div ar-contentedit="true" contenteditable="true" contenteditable="pla ...
- Alpha冲刺No.7
一.站立式会议 彻底完成初步的界面设计 实现界面的简单跳转 完成部分事件监听 移植摄像头.图库功能到真实手机环境测试 数据库上传获取日记 二.项目实际进展 完成了简单的界面设计 大致完成了跳转任务 数 ...