[日常摸鱼]UVA393 The Doors 简单计算几何+最短路

The  Boy Next   Doors

题意:给定一个固定大小的房间($x,y$的范围都是$[0,10]$),有$n$个墙壁作为障碍(都与横坐标轴垂直),每个墙壁都有两扇门分别用四个点来描述,起点终点固定在$(0,5)$和$(10,5)$,求起点到终点的最短路长度,$n<=18$



题解:

我们把每堵墙的每一“段”作为一条线段,对任意两点$u,v$,如果两点间的连线不和其他线段相交,那我们从$u$走到$v$的最短距离就是他们的欧几里得距离,对所有点对都这么做一遍,处理出所有能够直接到达的点之间的距离

如果不能直接从$u$到$v$,那么既然是最短路,那走直线一定比走曲线要好,也就是一定是经过他们中间的某些点然后到达的,然后对所有点跑一次最短路就好了

这题范围很小Floyd也能过…

  1 #include<cstdio>
  2 #include<cmath>
  3 #include<cstring>
  4 #include<algorithm>
  5 using namespace std;
  6
  7 const double precision=10e-6;
  8
  9 const double INF=(~0u>>2);
 10
 11 const int N=105;
 12
 13 struct Point
 14 {
 15     double x,y;
 16 }p[N];
 17
 18 struct Line
 19 {
 20     Point a,b;
 21 }l[N];
 22
 23 int n,cnt_point,cnt_line;
 24
 25 double dist[N][N];
 26
 27 inline int dblcmp(double d)
 28 {
 29     if(fabs(d)<precision)
 30         return 0;
 31     return (d>0?1:-1);
 32 }
 33
 34 inline double det(double x1,double y1,double x2,double y2)
 35 {
 36     return x1*y2-x2*y1;
 37 }
 38
 39 inline double cross(Point a,Point b,Point c)
 40 {
 41     return det(b.x-a.x,b.y-a.y,c.x-a.x,c.y-a.y);
 42 }
 43
 44 inline bool SegCrossSimple(Point a,Point b,Point c,Point d)
 45 {
 46     return (dblcmp(cross(c,a,b))^dblcmp(cross(d,a,b)))==-2&&(dblcmp(cross(a,c,d))^dblcmp(cross(b,c,d)))==-2;
 47 }
 48
 49 inline double sqr2(double x)
 50 {
 51     return x*x;
 52 }
 53
 54 inline double dis(int i,int j)
 55 {
 56     return sqrt(sqr2(p[i].x-p[j].x)+sqr2(p[i].y-p[j].y));
 57 }
 58
 59 inline void addPoint(double x,double y)
 60 {
 61     p[++cnt_point]=(Point){x,y};
 62 }
 63
 64 inline void addLine(double x1,double y1,double x2,double y2)
 65 {
 66     l[++cnt_line]=(Line){(Point){x1,y1},(Point){x2,y2}};
 67 }
 68
 69 inline void init()
 70 {
 71     memset(p,0,sizeof(p));
 72     memset(l,0,sizeof(l));
 73     cnt_point=cnt_line=0;
 74     addPoint(0,5);addPoint(10,5);
 75 }
 76
 77 inline void solve()
 78 {
 79     init();
 80
 81     double x,y1,y2,y3,y4;
 82     for(register int i=1;i<=n;i++)
 83     {
 84         scanf("%lf%lf%lf%lf%lf",&x,&y1,&y2,&y3,&y4);
 85         addPoint(x,y1);addPoint(x,y2);
 86         addPoint(x,y3);addPoint(x,y4);
 87         addLine(x,0,x,y1);addLine(x,y2,x,y3);addLine(x,y4,x,10);
 88     }
 89
 90     for(register int i=1;i<=cnt_point;i++)dist[i][i]=0;
 91
 92     for(register int i=1;i<=cnt_point;i++)
 93     {
 94         for(register int j=i+1;j<=cnt_point;j++)
 95         {
 96             bool flag=1;
 97             for(register int k=1;k<=cnt_line;k++)
 98             {
 99                 if(SegCrossSimple(p[i],p[j],l[k].a,l[k].b))
100                 {
101                     flag=0;
102                     break;
103                 }
104             }
105             if(flag)
106                 dist[i][j]=dis(i,j);
107             else
108                 dist[i][j]=INF;
109
110             dist[j][i]=dist[i][j];
111         }
112     }
113
114     for(register int k=1;k<=cnt_point;k++)
115         for(register int i=1;i<=cnt_point;i++)
116             for(register int j=1;j<=cnt_point;j++)if(dist[i][k]!=INF&&dist[k][j]!=INF)
117                 dist[i][j]=min(dist[i][j],dist[i][k]+dist[k][j]);
118
119     printf("%.2lf\n",dist[1][2]);
120 }
121
122 int main()
123 {
124     while(scanf("%d",&n)==1)
125     {
126         if(n==-1)break;
127         solve();
128     }
129     return 0;
130 }

时间: 2024-07-31 06:13:39

[日常摸鱼]UVA393 The Doors 简单计算几何+最短路的相关文章

[日常摸鱼]Uva11178Morley&#39;s Theorem-几何

题意:给一个$\Delta ABC$,分别做三个角的三等分线相交成$\Delta DEF$,求出$D,E,F$的坐标. 直接根据题意模拟 #include<cstdio> #include<cmath> #include<algorithm> using namespace std; struct Point { double x,y; Point(double x1=0,double y1=0){x=x1;y=y1;} }; typedef Point Vector;

POJ 1556 The Doors(简单计算几何+最短路)

●赘述题目 10*10的房间内,有竖着的一些墙(不超过18个).问从点(0,5)到(10,5)的最短路. 按照输入样例,输入的连续5个数,x,y1,y2,y3,y4,表示(x,0--y1),(x,y2--y3),(x,y4--10)是墙壁. ●题解 方法:建图(用到简单计算几何)+最短路 ○记录下每个端点. ○包含起点,终点,以及每个墙的可以走的端点,如下图: ○然后枚举点,尝试两两组合连(线段)边,若该线不会撞在墙上,即不会与墙壁线段相交,就add_adge(). 效果图如下: 如何判断呢?

[日常摸鱼]bzoj1502[NOI2005]月下柠檬树-简单几何+Simpson法

关于自适应Simpson法的介绍可以去看我的另一篇blog http://www.lydsy.com/JudgeOnline/problem.php?id=1502 题意:空间里圆心在同一直线上且底面与地面平行的若干个圆台和顶层的圆锥以$\alpha$的角度投影到地面,求投影的面积. (其实我是看po姐博客来的x) 首先把圆锥的顶点也看成一个半径为0的圆满,对于每个高度为$h$的圆投影下去的坐标是$h/tan(\alpha)$,半径不变,而对于圆台的侧面投影下去是上下底两个圆的切线. 关于两个圆

[日常摸鱼]JSOI2008最大数

校运会的时候随手抽的题- 一句话题意 维护一个序列,初始为空,要求滋兹: 1.查询这个序列末尾$x$个数的最大值 2.设上一次查询的答案为$t$(如果还没查询$t=0$),在末尾插入一个数$(x+t)mod d$,$d$为给定常数 很容易想到用线段树做:记录序列的末尾,然后直接单点修改区间查询 本来想随便写完就过了的-然后一直爆零- 因为我写了一句 while(n--) 然后这题应该就没什么要注意的地方了233 贴代码 #include<cstdio> #include<cstring&

[日常摸鱼]杜教筛

因为博主比较菜所以可能一些地方写的有问题或者不清楚,以及我的废话有点多- 在这里先感谢下小伙伴ww @MoebiusMeow 的帮助~ 参考资料: [1]浅谈一类积性函数的前缀和(skywalkert) [2]杜教筛--省选前的学习1(_rqy) (下面约定$[p]$表示满足条件$p$时为1不满足为0,以及下面说的函数都是数论函数) 前置技能(一些定义) 数论函数:若$f:Z^{+} \rightarrow C$,则称$f$为数论函数 积性函数:若一个数论函数$f(n)$对于所有$m_1 \bo

[日常摸鱼]字符串相关

最近开始学字符串-之前暑假听JOHNKROM大爷讲这个的时候就很懵(当时根本没碰过这个东西-) 这里大概会有一些相关的算法和自己做的题,还有存一些模板啥的. 由于我太弱了所以可能不会写有关原理的东西(或者等我哪天会了有空再补)如果是刚学的话还是去网上找教程吧-我就存个题还有模板啥的orz Trie字典树(Trie),根节点为空节点,其他节点(或边上)放字母,然后节点上还能储存一些其他信息. 1.一个类似模板题的东西:luogu2580 建一颗Trie,把所有名字插进去,结束的地方打个标记,具体见

[日常摸鱼]luogu1613跑路

新年A的第一道题2333 https://www.luogu.org/problemnew/show/P1613 题意:给一张有向图,每条边长为1,每个单位时间只能走$2^k$的长度,$k$可以任意选,问从起点到终点的最短时间 我好菜呀一看到题还是不会做orz 我们用一个$G[i][j][k]$数组来表示$i$到$j$是否存在$2^k$的路径,用$dis[i][j]$表示$i$到$j$需要的最短时间,有连边的两个点就直接让$G[i][j][0]=1,dis[i][j]=1$,然后类似倍增那样子去

[日常摸鱼]luogu3398仓鼠找sugar-树链剖分

https://www.luogu.org/problemnew/show/P3398 题意:一颗$n$个点的树,$q$次询问两条链$(a,b),(c,d)$是否有交 树剖裸题orz 一开始的想法是求出$lca_1=lca(a,b),lca_2=lca(c,d)$,对于深度大的那个$lca$用dfs序判断是否在另一条链上,然后到现在都不知道为什么一直wa- 改成判断深度大的那个$lca$是否和另外两个点的其中某个点有父子关系好像就行了- #include<cstdio> #include<

[日常摸鱼][POI2000]病毒-Tire图(AC自动机)+dfs

https://www.luogu.org/problemnew/show/P2444 (没有bzoj权限号T_T) 字符串题对我这种傻逼来说真是太难了x 题意:输入$n$个01组成的模式串串,判断是否存在一个无限长的01串满足任何给定的模式串都不是这个串的子串,$n \leq 2000,\sum len(str) \leq 30000$ 首先用模式串构造出AC自动机(其实应该叫Trie图),题目要求的串如果存在,那就相当于在Trie图上存在一个环,这个环不包含任何一个模式串,所以只要构造出来T