题目链接:The Doors - POJ 1556 - Virtual Judge  https://vjudge.net/problem/POJ-1556

题意是叫我们计算从(0,5)到(10,5)的最短路,中间会给出n道墙,每道墙会有两扇门可以通过,第一行是数字n,接下来n行,每行有x,y1,y2,y3,y4,表示横坐标为x的门上的四个点坐标。

在这里主要是把图建出来,我的做法是先把所有点和墙存下来,然后枚举每两点,这两点要满足横坐标不同,并且两点的连线不经过在两点的横坐标之间的墙,假设我们有两个点p1,p2,有一道墙的横坐标是x,那么只要(p1.x-x)*(p2.x-x)<0,这两个点就在墙的左右两边,然后再判断和墙有没有交点,这个用叉积计算墙的两点是不是在我们两点连线的两边,把图建完就用floyd或者dijkstra计算一下最短路就可以了,可能讲的不是很清楚,看一下代码:

struct node{
double x,y;
}p[];  //存点
struct ss{
node a,b;
}wall[];//存墙

我写的有点麻烦:

     p[].x=,p[].y=;
p[].x=,p[].y=;//起点和终点分别存进去
cnt1=;    //点的数量
cnt2=;    //墙的数量
for(int i=;i<n;i++)
{
double x,y;
cin>>x;
cin>>y;
p[cnt1].x=x,p[cnt1].y=y;  //第一个点
wall[cnt2].a=p[cnt1];    //第一道墙
wall[cnt2].b.x=x;
wall[cnt2].b.y=;
cnt1++;
cnt2++; cin>>y;
p[cnt1].x=x,p[cnt1].y=y;  //第二个点
cnt1++; cin>>y;
p[cnt1].x=x,p[cnt1].y=y;  //第三个点 wall[cnt2].a=p[cnt1];
wall[cnt2].b=p[cnt1-];  //第二道墙
cnt1++;
cnt2++; cin>>y;
p[cnt1].x=x,p[cnt1].y=y;  //第四个点和第三道墙,好麻烦
wall[cnt2].a=p[cnt1];
wall[cnt2].b.x=x;
wall[cnt2].b.y=;
cnt1++;
cnt2++;
}

判断两点之间有没有墙

bool jug(int a,int b)
{
for(int i=;i<cnt2;i++)
{
double x=wall[i].a.x;
double k=(p[a].x-x)*(p[b].x-x);    //判断墙在两点之间
double k1=cross(p[a],p[b],wall[i].a);//判断墙的两点是否在连点的直线两边
double k2=cross(p[a],p[b],wall[i].b);
if(k<&&k1*k2<eps)
return true;
}
return false;
}

完整代码:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define eps 1e-10
#define inf 9999999
struct node{
double x,y;
}p[];
struct ss{
node a,b;
}wall[];
double map[][];
int n,m,k,t,cnt1,cnt2;
double dis(node a,node b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double cross(node a,node b,node c)
{
return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);
}
bool jug(int a,int b)
{
for(int i=;i<cnt2;i++)
{
double x=wall[i].a.x;
double k=(p[a].x-x)*(p[b].x-x);
double k1=cross(p[a],p[b],wall[i].a);
double k2=cross(p[a],p[b],wall[i].b);
if(k<&&k1*k2<eps)
return true;
}
return false;
}
void floyd()
{
for(int k=;k<cnt1;k++)
{
for(int i=;i<cnt1;i++)
{
for(int j=;j<cnt1;j++)
{
if(i!=j&&map[i][j]>map[i][k]+map[k][j])
{
map[i][j]=map[i][k]+map[k][j];
}
}
}
}
}
int main()
{
while(cin>>n)
{
if(n<)
break;
p[].x=,p[].y=;
p[].x=,p[].y=;
cnt1=;
cnt2=;
for(int i=;i<n;i++)
{
double x,y;
cin>>x;
cin>>y;
p[cnt1].x=x,p[cnt1].y=y;
wall[cnt2].a=p[cnt1];
wall[cnt2].b.x=x;
wall[cnt2].b.y=;
cnt1++;
cnt2++; cin>>y;
p[cnt1].x=x,p[cnt1].y=y;
cnt1++; cin>>y;
p[cnt1].x=x,p[cnt1].y=y; wall[cnt2].a=p[cnt1];
wall[cnt2].b=p[cnt1-];
cnt1++;
cnt2++; cin>>y;
p[cnt1].x=x,p[cnt1].y=y;
wall[cnt2].a=p[cnt1];
wall[cnt2].b.x=x;
wall[cnt2].b.y=;
cnt1++;
cnt2++;
}
for(int i=;i<cnt1;i++)
{
for(int j=;j<cnt1;j++)
map[i][j]=inf;
}
for(int i=;i<cnt1-;i++)
{
for(int j=i+;j<cnt1;j++)
{
if(i!=j&&p[i].x!=p[j].x&&!jug(i,j))
{
map[i][j]=map[j][i]=dis(p[i],p[j]);
}
}
}
floyd();
printf("%.2f\n",map[][]);
}
return ;
}

最短路+叉积 poj1556的更多相关文章

  1. POJ1556 The Doors 叉积+最短路

    题目大意:求从(0,5)到(10,5)的最短距离,起点与终点之间有n堵墙,每个墙有2个门. 题目思路:判断两点间是否有墙(判断两点的连线是否与某一堵墙的线段相交),建立一个图,然后最短路求出就可以了. ...

  2. poj1556 The Doors(叉积判断线段相交)

    题目链接:https://vjudge.net/problem/POJ-1556 题意:在一个矩形内,起点(0,5)和终点(10,5)是固定的,中间有n个道墙(n<=18),每道墙有两个門,求起 ...

  3. POJ1556 最短路 + 线段相交问题

    POJ1556 题目大意:比较明显的题目,在一个房间中有几堵墙,直着走,问你从(0,5)到(10,5)的最短路是多少 求最短路问题,唯一变化的就是边的获取,需要我们获取边,这就需要判断我们想要走的这条 ...

  4. POJ-1556 The Doors---线段相交+最短路

    题目链接: https://vjudge.net/problem/POJ-1556 题目大意: 给一个10*10的正方形房间中间用墙隔开每个墙上有两个门,给出门的两个端点坐标求从左边中点走到右边中点所 ...

  5. 2018.07.06 POJ1556 The Doors(最短路)

    The Doors Time Limit: 1000MS Memory Limit: 10000K Description You are to find the length of the shor ...

  6. POJ 1556 The Doors【最短路+线段相交】

    思路:暴力判断每个点连成的线段是否被墙挡住,构建图.求最短路. 思路很简单,但是实现比较复杂,模版一定要可靠. #include<stdio.h> #include<string.h ...

  7. 简单几何(线段相交+最短路) POJ 1556 The Doors

    题目传送门 题意:从(0, 5)走到(10, 5),中间有一些门,走的路是直线,问最短的距离 分析:关键是建图,可以保存所有的点,两点连通的条件是线段和中间的线段都不相交,建立有向图,然后用Dijks ...

  8. BZOJ 2433 智能车比赛(计算几何+最短路)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2433 题意:若干个矩形排成一排(同一个x之上最多有一个矩形),矩形i和i+1相邻.给定两 ...

  9. POJ 1556 The Doors(计算几何+最短路)

    这题就是,处理出没两个点.假设能够到达,就连一条边,推断可不能够到达,利用线段相交去推断就可以.最后求个最短路就可以 代码: #include <cstdio> #include < ...

随机推荐

  1. python语言程序设计-北京理工大学-嵩天等课件代码整理

    #TempConvert.py TempStr = input("请输入带有符号的温度值: ") if TempStr[-1] in ['F', 'f']: C = (eval(T ...

  2. [ilink32 Error] Fatal: Unable to open file 'DATA.DBXMSSQLMETADATAREADER.OBJ'

    [ilink32 Error] Fatal: Unable to open file 'DATA.DBXMSSQLMETADATAREADER.OBJ' 清除重新编译OK

  3. day29-序列化 json、pickle、shelve

    1.pickle和JSON序列化 如果我们想用文本文件保存一个 Python 对象怎么操作?这里就涉及到序列化的问题,序列化指的是将原本的字典.列表等内容转换成一个字符串的过程. 2.为什么要使用序列 ...

  4. mysqldump备份时保持数据一致性

    对MySQL数据进行备份,常见的方式如以下三种,可能有很多人对备份时数据一致性并不清楚 1.直接拷贝整个数据目录下的所有文件到新的机器.优点是简单.快速,只需要拷贝:缺点也很明显,在整个备份过程中新机 ...

  5. netty ChannelOption

    项目中用到很多netty,配置了各种不同的ChannelOption优化项,不同的配置对于在高并发情况下的性能有不小的影响 首先看下全部项目,参考下这篇文章,虽然不全 https://www.cnbl ...

  6. Linux删除ORACLE数据库用户失败提示ORA-01940解决方法

    操作环境 SuSE11+Oracle11gR2 问题现象 删除ORACLE数据库用户失败,提示ORA-01940: cannot drop a user that is currently conne ...

  7. 关于PHP Notice: A non well formed numeric value encountered, 你知道多少

    ---------------------------------------------------------------------------------------------- A non ...

  8. Python异常和调试.md

    异常捕获 try 基本概念 我们使用try except来捕获异常,python的try except有几个特点: 不管函数内部嵌套几层,只要在try的范围内就可以被捕获.这句话的意思是一个函数被tr ...

  9. 自定义 mapper的实现

    json格式,要想好看直接百度,json,将字符放进去就可 一步:将mapper复制一份,名字加一个Custom自定义 二步:mpper.xml也是一样,设置里面的namespace映射关系 自定义m ...

  10. mysql 查询上个月某一天

    本文地址:http://www.cnblogs.com/jying/p/8877065.html 需求:获取上个月15号的日期 网上一搜一大堆粘贴复制的大坑:(如下是查询上个月最后一天,可是我要的不一 ...