POJ 2556 (判断线段相交 + 最短路)
题目: 传送门
题意:在一个左小角坐标为(0, 0),右上角坐标为(10, 10)的房间里,有 n 堵墙,每堵墙都有两个门。每堵墙的输入方式为 x, y1, y2, y3, y4,x 是墙的横坐标,第一个门的区间为[ (x, y1) ~ (x, y2) ],问你从 (0, 5) 走到 (10, 5) 的最短路径是多少。
0 <= n <= 18
题解:讲每个门的端点存起来,然后,加上(0, 5) 和 (10, 5) 这两个点,暴力判断这些点两两间是否能互相直达,然后再跑一遍最短路就行了。
你不能直接从 (0, 5) 到 (10, 5) 那你肯定是经过一些门的端点再到终点是最优的。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
#include <map>
#include <vector>
#include <set>
#include <string>
#include <math.h>
#define LL long long
#define mem(i, j) memset(i, j, sizeof(i))
#define rep(i, j, k) for(int i = j; i <= k; i++)
#define dep(i, j, k) for(int i = k; i >= j; i--)
#define pb push_back
#define make make_pair
#define INF 1e20
#define inf LLONG_MAX
#define PI acos(-1)
using namespace std; const int N = 1e2 + ;
const double eps = 1e-; struct Point {
double x, y;
Point(double x = , double y = ) : x(x), y(y) { } /// 构造函数
}; /// 向量加减乘除
inline Point operator + (const Point& A, const Point& B) { return Point(A.x + B.x, A.y + B.y); }
inline Point operator - (const Point& A, const Point& B) { return Point(A.x - B.x, A.y - B.y); }
inline Point operator * (const Point& A, const double& p) { return Point(A.x * p, A.y * p); }
inline Point operator / (const Point& A, const double& p) { return Point(A.x / p, A.y / p); } inline int dcmp(const double& x) { if(fabs(x) < eps) return ; else return x < ? - : ; } inline double Cross(const Point& A, const Point& B) { return A.x * B.y - A.y * B.x; } /// 叉积
inline double Dot(const Point& A, const Point& B) { return A.x * B.x + A.y * B.y; } /// 点积
inline double Length(const Point& A) { return sqrt(Dot(A, A)); } /// 向量长度
inline double Angle(const Point& A, const Point& B) { return acos(Dot(A, B) / Length(A) / Length(B)); } /// 向量A,B夹角 inline Point GetLineIntersection(const Point P, const Point v, const Point Q, const Point w) {///求直线p + v*t 和 Q + w*t 的交点,需确保有交点,v和w是方向向量
Point u = P - Q;
double t = Cross(w, u) / Cross(v, w);
return P + v * t;
} inline bool Onsegment(Point p, Point a1, Point a2) { /// 判断点p是否在线段p1p2上
return dcmp(Cross(a1 - p, a2 - p)) == && dcmp(Dot(a1 - p, a2 - p)) <= ;
} inline bool SegmentProperInsection(Point a1, Point a2, Point b1, Point b2) { /// 判断线段是否相交
if(dcmp(Cross(a1 - a2, b1 - b2)) == ) /// 两线段平行
return Onsegment(b1, a1, a2) || Onsegment(b2, a1, a2) || Onsegment(a1, b1, b2) || Onsegment(a2, b1, b2);
Point tmp = GetLineIntersection(a1, a2 - a1, b1, b2 - b1);
return Onsegment(tmp, a1, a2) && Onsegment(tmp, b1, b2);
} Point P[N];
double dis[N][N];
int main() {
int n;
double x, y1, y2, y3, y4;
while(scanf("%d", &n) && n != -) { int cnt = ;
rep(i, , n) {
scanf("%lf %lf %lf %lf %lf", &x, &y1, &y2, &y3, &y4);
P[++cnt] = Point(x, y1);
P[++cnt] = Point(x, y2);
P[++cnt] = Point(x, y3);
P[++cnt] = Point(x, y4);
} rep(i, , cnt + ) rep(j, , cnt + ) if(i == j) dis[i][j] = ; else dis[i][j] = INF; rep(i, , cnt) { /// 判断(0,5)是否能直达P[i],P[i]是否能直达(10,5)
bool flag = ;
int up = ((i + ) / ) * + ;
up -= ;
for(int j = ; j < up; j += ) { /// (0,5)是否能直达P[i]
if(SegmentProperInsection(P[j], P[j + ], Point(, ), P[i]) == false && SegmentProperInsection(P[j + ], P[j + ], Point(, ), P[i]) == false) flag = ;
}
if(!flag) dis[][i] = dis[i][] = Length(Point(, ) - P[i]); flag = ;
for(int j = up + ; j <= cnt; j += ) { /// P[i] 是否能直达(10,5)
if(SegmentProperInsection(P[j], P[j + ], Point(, ), P[i]) == false && SegmentProperInsection(P[j + ], P[j + ], Point(, ), P[i]) == false) flag = ;
}
if(!flag) dis[cnt + ][i] = dis[i][cnt + ] = Length(Point(, ) - P[i]);
} rep(i, , cnt) rep(j, i + , cnt) { /// 枚举两点,判断这两点是否能直达
int st = ((i + ) / ) * + ;
int ed = ((j + ) / ) * ;
bool flag = ;
for(int k = st; k <= ed; k += ) {
if(SegmentProperInsection(P[k], P[k + ], P[i], P[j]) == false && SegmentProperInsection(P[k + ], P[k + ], P[i], P[j]) == false) flag = ;
}
if(!flag) dis[i][j] = dis[j][i] = Length(P[i] - P[j]);
} bool flag = ;
for(int i = ; i <= cnt; i += ) /// 判断(0,5)是否能直达(10,5)
if(SegmentProperInsection(P[i], P[i + ], Point(, ), Point(, )) == false && SegmentProperInsection(P[i + ], P[i + ], Point(, ), Point(, )) == false) flag = ;
if(!flag) dis[][cnt + ] = dis[cnt + ][] = ; rep(k, , cnt + ) rep(i, , cnt + ) rep(j, , cnt + )
if(dis[i][k] + dis[k][j] < dis[i][j]) dis[i][j] = dis[i][k] + dis[k][j];
printf("%.2f\n", dis[][cnt + ]);
}
return ;
}
POJ 2556 (判断线段相交 + 最短路)的更多相关文章
- POJ_1556_The Doors_判断线段相交+最短路
POJ_1556_The Doors_判断线段相交+最短路 Description You are to find the length of the shortest path through a ...
- POJ 1556 计算几何 判断线段相交 最短路
题意: 在一个左下角坐标为(0,0),右上角坐标为(10,10)的矩形内,起点为(0,5),终点为(10,5),中间会有许多扇垂直于x轴的门,求从起点到终点在能走的情况下的最短距离. 分析: 既然是求 ...
- C - Segments POJ - 3304 (判断线段相交)
题目链接:https://vjudge.net/contest/276358#problem/C 题目大意:给你n条线段,问你是否存在一条线段使得所有的线段在这条直线的投影至少具有一个交点? 具体思路 ...
- POJ 3449 /// 判断线段相交
题目大意: 给出多个多边形及其编号 按编号顺序输出每个多边形与其相交的其他多边形编号 注意一个两个多个的不同输出 将每个多边形处理成多条边 然后去判断与其他多边形的边是否相交 计算正方形另外两点的方法 ...
- 简单几何(线段相交+最短路) POJ 1556 The Doors
题目传送门 题意:从(0, 5)走到(10, 5),中间有一些门,走的路是直线,问最短的距离 分析:关键是建图,可以保存所有的点,两点连通的条件是线段和中间的线段都不相交,建立有向图,然后用Dijks ...
- POJ 2826 An Easy Problem? 判断线段相交
POJ 2826 An Easy Problem?! -- 思路来自kuangbin博客 下面三种情况比较特殊,特别是第三种 G++怎么交都是WA,同样的代码C++A了 #include <io ...
- 【POJ 2653】Pick-up sticks 判断线段相交
一定要注意位运算的优先级!!!我被这个卡了好久 判断线段相交模板题. 叉积,点积,规范相交,非规范相交的简单模板 用了“链表”优化之后还是$O(n^2)$的暴力,可是为什么能过$10^5$的数据? # ...
- POJ 2653 Pick-up sticks(判断线段相交)
Pick-up sticks Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 7699 Accepted: 2843 De ...
- POJ 1066--Treasure Hunt(判断线段相交)
Treasure Hunt Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 7857 Accepted: 3247 Des ...
随机推荐
- docker相关----解决tomcat容器启动成功,无法访问的问题
使用docker安装了tomcat镜像,默认为latest最新的(8.5.50版本),依据tomcat镜像创建容器并同时做了端口映射 命令为:docker run --name tomcat01 -d ...
- Boyer-Moore 算法 Leetcode169
Boyer-Moore 算法 Leetcode169 一.题目 169. 多数元素 给定一个大小为 n 的数组,找到其中的多数元素.多数元素是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素. 你可以假 ...
- C++不同类中的特征标相同的同名函数
转载请注明出处,版权归作者所有 lyzaily@126.com yanzhong.lee 作者按: 从这篇文章中,我们主要会认识到一下几点: ...
- 视觉slam十四讲课后习题ch3--5题
题目回顾: 假设有一个大的Eigen矩阵,我想把它的左上角3x3块提取出来,然后赋值为I3x3.编程实现.解:提取大矩阵左上角3x3矩阵,有两种方式: 1.直接从0-2循环遍历大矩阵的前三行和三列 2 ...
- 【MySQL 原理分析】之 Trace 分析 order by 的索引原理
一.背景 昨天早上,交流群有一位同学提出了一个问题.看下图: 我不是大佬,而且当时我自己的想法也只是猜测,所以并没有回复那位同学,只是接下来自己做了一个测试验证一下. 他只简单了说了一句话,就是同样的 ...
- Codeforces_832
A.判断n/k的奇偶性. #include<bits/stdc++.h> using namespace std; long long n,k; int main() { ios::syn ...
- 《Python学习手册 第五版》 -第8章 列表与字典
前面已经讲过数值类型(第5章)和字符串类型(第7章),本章继续其他数据类型的讲解:列表和字典 本章的核心内容 1.列表 1)什么是列表 2)基本列表操作 3)列表迭代和推导 4)索引.分片和矩阵 5) ...
- asp.net core系列 WebAPI 作者:懒懒的程序员一枚
asp.net core系列 36 WebAPI 搭建详细示例一.概述1.1 创建web项目1.2 添加模型类1.3 添加数据库上下文1.4 注册上下文1.5 添加控制器1.6 添加Get方法1.7 ...
- 提升命令行效率的Bash快捷键
转自:http://linuxtoy.org/archives/bash-shortcuts.html 生活在 Bash shell 中,熟记以下快捷键,将极大的提高你的命令行操作效率. 大部分对其他 ...
- 手把手带你阅读Mybatis源码(二)执行篇
前言 上一篇文章提到了MyBatis是如何构建配置类的,也说了MyBatis在运行过程中主要分为两个阶段,第一是构建,第二就是执行,所以这篇文章会带大家来了解一下MyBatis是如何从构建完毕,到执行 ...