poj1556 The Doors(叉积判断线段相交)
题目链接:https://vjudge.net/problem/POJ-1556
题意:在一个矩形内,起点(0,5)和终点(10,5)是固定的,中间有n个道墙(n<=18),每道墙有两个門,求起点到终点的最短路。
思路:
最多有4*n+2个点,枚举所有点对(p1,p2),用叉积判断线段p1p2和中间的墙是否相交,不相交那么更新距离为两点的距离,否则为inf。更新所有的边之后用floyd得到最短路。答案即dist[0][4*n+1]。时间复杂度O(n^3)。
AC code:
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstdlib>
using namespace std; const int maxn=;
const double eps=1e-;
const double inf=1e20;
int n;
double dist[maxn][maxn]; int sgn(double x){
if(abs(x)<eps) return ;
if(x<) return -;
return ;
} struct Point{
double x,y;
Point(){}
Point(double xx,double yy):x(xx),y(yy){}
Point operator + (const Point& b){
return Point(x+b.x,y+b.y);
}
Point operator - (const Point& b){
return Point(x-b.x,y-b.y);
}
double operator * (const Point& b){
return x*b.x+y*b.y;
}
double operator ^ (const Point& b){
return x*b.y-b.x*y;
}
}; struct Line{
Point s,e;
Line(){}
Line(Point ss,Point ee){
s=ss,e=ee;
}
}line[maxn]; 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((l1.s-l2.s)^(l2.e-l2.s))*sgn((l1.e-l2.s)^(l2.e-l2.s))<=&&
sgn((l2.s-l1.s)^(l1.e-l1.s))*sgn((l2.e-l1.s)^(l1.e-l1.s))<=;
} double dis(Point a,Point b){
return sqrt((b-a)*(b-a));
} int main(){
while(scanf("%d",&n),n!=-){
double x,yy1,yy2,yy3,yy4;
for(int i=;i<=n;++i){
scanf("%lf%lf%lf%lf%lf",&x,&yy1,&yy2,&yy3,&yy4);
line[*i-]=Line(Point(x,yy1),Point(x,yy2));
line[*i]=Line(Point(x,yy3),Point(x,yy4));
}
for(int i=;i<=*n+;++i)
for(int j=;j<=*n+;++j)
if(i==j) dist[i][j]=;
else dist[i][j]=inf;
for(int i=;i<=*n;++i){
int id=(i+)/;
Point tmp;
if(i&) tmp=line[(i+)/].s;
else tmp=line[(i+)/].e;
int flag=;
for(int j=;j<id;++j)
if(!inter(Line(Point(,),tmp),line[*j-])&&
!inter(Line(Point(,),tmp),line[*j])){
flag=;break;
}
if(flag) dist[][i]=dist[i][]=dis(Point(,),tmp);
flag=;
for(int j=id+;j<=n;++j)
if(!inter(Line(tmp,Point(,)),line[*j-])&&
!inter(Line(tmp,Point(,)),line[*j])){
flag=;break;
}
if(flag) dist[*n+][i]=dist[i][*n+]=dis(tmp,Point(,));
}
for(int i=;i<=*n;++i)
for(int j=i+;j<=*n;++j){
int id1=(i+)/,id2=(j+)/;
int flag=;
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=id1+;k<id2;++k)
if(!inter(Line(p1,p2),line[*k-])&&
!inter(Line(p1,p2),line[*k])){
flag=;break;
}
if(flag) dist[i][j]=dist[j][i]=dis(p1,p2);
}
int flag=;
for(int i=;i<=n;++i)
if(!inter(Line(Point(,),Point(,)),line[*i-])&&
!inter(Line(Point(,),Point(,)),line[*i])){
flag=;break;
}
if(flag) dist[][*n+]=dist[*n+][]=;
for(int k=;k<=*n+;++k)
for(int i=;i<=*n+;++i)
for(int j=;j<=*n+;++j)
dist[i][j]=min(dist[i][j],dist[i][k]+dist[k][j]);
printf("%.2f\n",dist[][*n+]);
}
return ;
}
poj1556 The Doors(叉积判断线段相交)的更多相关文章
- POJ 1066--Treasure Hunt(判断线段相交)
Treasure Hunt Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 7857 Accepted: 3247 Des ...
- 【POJ 2653】Pick-up sticks 判断线段相交
一定要注意位运算的优先级!!!我被这个卡了好久 判断线段相交模板题. 叉积,点积,规范相交,非规范相交的简单模板 用了“链表”优化之后还是$O(n^2)$的暴力,可是为什么能过$10^5$的数据? # ...
- hdu 1086(判断线段相交)
传送门:You can Solve a Geometry Problem too 题意:给n条线段,判断相交的点数. 分析:判断线段相交模板题,快速排斥实验原理就是每条线段代表的向量和该线段的一个端点 ...
- POJ_1066_Treasure Hunt_判断线段相交
POJ_1066_Treasure Hunt_判断线段相交 Description Archeologists from the Antiquities and Curios Museum (ACM) ...
- POJ_2653_Pick-up sticks_判断线段相交
POJ_2653_Pick-up sticks_判断线段相交 Description Stan has n sticks of various length. He throws them one a ...
- POJ 2826 An Easy Problem? 判断线段相交
POJ 2826 An Easy Problem?! -- 思路来自kuangbin博客 下面三种情况比较特殊,特别是第三种 G++怎么交都是WA,同样的代码C++A了 #include <io ...
- 还记得高中的向量吗?leetcode 335. Self Crossing(判断线段相交)
传统解法 题目来自 leetcode 335. Self Crossing. 题意非常简单,有一个点,一开始位于 (0, 0) 位置,然后有规律地往上,左,下,右方向移动一定的距离,判断是否会相交(s ...
- POJ 2653 Pick-up sticks(判断线段相交)
Pick-up sticks Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 7699 Accepted: 2843 De ...
- 判断线段相交(hdu1558 Segment set 线段相交+并查集)
先说一下题目大意:给定一些线段,这些线段顺序编号,这时候如果两条线段相交,则把他们加入到一个集合中,问给定一个线段序号,求在此集合中有多少条线段. 这个题的难度在于怎么判断线段相交,判断玩相交之后就是 ...
随机推荐
- Tpcc-mysql 结果解读
原文:https://blog.csdn.net/frockee/article/details/87812329 1. 填坑经验 不要使用tidb的tpcc测试程序(非标准,tidb修改过),使 ...
- Comet OJ - Contest #2 (D 错综的光影所迷惑的思念是) 容斥计数
题意:给定一颗 $n$ 个节点的树,定义 $dis(x,y)$ 为树上点 $x$ 到 $y$ 的路径经过的边数. 定义一个点集 $S$ 的 $f(S)$ 为 $f(S)=max\left \{dis( ...
- linux crontab 防止周期内为执行完成重复执行
问题的背景: 我们常常需要通过crontab部署某个脚本运行某些定时任务,但在实际的过程中,一旦处理不好可能导致在同一时刻出现脚本的多个运行副本,比如crontab的调度是每5 分钟运行一次脚本,如果 ...
- 字典-Python基础前传(9)
(一)Python中为什么要有字典 jacky说科学存在的逻辑只有两个: 1.解释问题 2.解决问题 我们明白了科学的逻辑,我们理解任何的知识和技能,都是很简单的 之前jacky跟大家说list因为太 ...
- java并发编程--第一章并发编程的挑战
一.java并发编程的挑战 并发编程需要注意的问题: 并发编程的目的是让程序运行的更快,然而并不是启动更多的线程就能让程序最大限度的并发执行.若希望通过多线程并发让程序执行的更快,会受到如下问题的挑战 ...
- golang sqlx查询时, struct字段冲突
type TA struct { Id int64 `db:"id"` } type TB struct { Id int64 `db:"id"` } type ...
- --thunder-lock is available since uWSGI 1.4.6 but never got documentation (of any kind)
--thunder-lock is available since uWSGI 1.4.6 but never got documentation (of any kind) Serializing ...
- Vue UI组件库
1. iView UI组件库 iView官网:https://www.iviewui.com/ 2.Vux UI组件库 Vux官网:https://vux.li/ 3.Element UI组件库 ...
- python实现并发服务器实现方式(多线程/多进程/select/epoll)
python实现并发服务器实现方式(多线程/多进程/select/epoll) 并发服务器开发 并发服务器开发,使得一个服务器可以近乎同一时刻为多个客户端提供服务.实现并发的方式有多种,下面以多进 ...
- 整理了一份比较全面的PHP开发编码规范.
这些年来多从事Linux下PHP和C相关的开发,带过很多项目和团队,下面是根据经验整理的PHP编码规范,可以用作给大家的范例和参考,根据需要进行取舍和修改! (可能最新的一些php5的规范不够完整,今 ...