题目链接: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(叉积判断线段相交)的更多相关文章

  1. POJ 1066--Treasure Hunt(判断线段相交)

    Treasure Hunt Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7857   Accepted: 3247 Des ...

  2. 【POJ 2653】Pick-up sticks 判断线段相交

    一定要注意位运算的优先级!!!我被这个卡了好久 判断线段相交模板题. 叉积,点积,规范相交,非规范相交的简单模板 用了“链表”优化之后还是$O(n^2)$的暴力,可是为什么能过$10^5$的数据? # ...

  3. hdu 1086(判断线段相交)

    传送门:You can Solve a Geometry Problem too 题意:给n条线段,判断相交的点数. 分析:判断线段相交模板题,快速排斥实验原理就是每条线段代表的向量和该线段的一个端点 ...

  4. POJ_1066_Treasure Hunt_判断线段相交

    POJ_1066_Treasure Hunt_判断线段相交 Description Archeologists from the Antiquities and Curios Museum (ACM) ...

  5. POJ_2653_Pick-up sticks_判断线段相交

    POJ_2653_Pick-up sticks_判断线段相交 Description Stan has n sticks of various length. He throws them one a ...

  6. POJ 2826 An Easy Problem? 判断线段相交

    POJ 2826 An Easy Problem?! -- 思路来自kuangbin博客 下面三种情况比较特殊,特别是第三种 G++怎么交都是WA,同样的代码C++A了 #include <io ...

  7. 还记得高中的向量吗?leetcode 335. Self Crossing(判断线段相交)

    传统解法 题目来自 leetcode 335. Self Crossing. 题意非常简单,有一个点,一开始位于 (0, 0) 位置,然后有规律地往上,左,下,右方向移动一定的距离,判断是否会相交(s ...

  8. POJ 2653 Pick-up sticks(判断线段相交)

    Pick-up sticks Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 7699   Accepted: 2843 De ...

  9. 判断线段相交(hdu1558 Segment set 线段相交+并查集)

    先说一下题目大意:给定一些线段,这些线段顺序编号,这时候如果两条线段相交,则把他们加入到一个集合中,问给定一个线段序号,求在此集合中有多少条线段. 这个题的难度在于怎么判断线段相交,判断玩相交之后就是 ...

随机推荐

  1. 用pyinstaller打包python程序、打包pyqt程序

    将.py脚本拷贝到一个文件夹中: 然后shift+右键,打开Powershell窗口: -F:设置打包为一个.exe文件.(缺点打开速度慢,不加-F则不打包为一个.exe,优点简洁方便) -w:设置不 ...

  2. PHP mysqli_connect_error() 函数

    返回上一次连接错误的错误描述: <?php $con=mysqli_connect("localhost","wrong_user","my_p ...

  3. ODBC连接到400

    1.首先iSeries Client安装的时候要勾选ODBC , 这样才能找到Driver 2.某个Application是32位上,要用32位路径下的ODBC Administration打开,添加 ...

  4. MySQL数据分析-(1) 数据库前言

    (一)开场白 大家好,欢迎大家跟我一起学习<MySQL数据分析实战>这门课程,对于数据分析师来说,数据库是每一个从业者都必须掌握的课程,我们这门课是从实战的角度出发,我会帮助大家梳理MyS ...

  5. loadrunner11安装

    今天虚拟机里面装了下lr11,虚拟机版本是vm9.0,先在虚拟机里面装了windows2003,当然lr也是可以装在自己电脑上面的,但是最好是纯净的环境,由于我电脑东西比较多,所以我就装在虚拟机里面了 ...

  6. springboot 出现 org.hibernate.LazyInitializationException: could not initialize proxy

    org.hibernate.LazyInitializationException: could not initialize proxy [com.example.shop.dataobject.U ...

  7. 使用es6一句话去重

    let arr = [1,2,3,4,5,1,2,3] let arr2 = Array.from(new Set(arr)) console.log(arr2) //[1,2,3,4,5]

  8. sql控制流if()、case when then

    tb_user: 1.if (expr1,expr2,expr3) #如果expr1成立,则返回expr2,否则返回expr3示例:select  name, if (sex=1,'男','女')  ...

  9. C++ STL Heap算法

    #include <iostream>#include <algorithm>#include <vector> using namespace std; int ...

  10. 阶段5 3.微服务项目【学成在线】_day04 页面静态化_17-页面静态化-模板管理-GridFS研究-存文件

    将模板信息保存在cms_template里面 存储在fs.chunks这个集合中.这个集合里面存的是分块文件. fs.files存的是文件的基本信息 chunks存的是块信息 创建测试文件 在cms的 ...