题意:

一个正方形中有n道竖直的墙,每道墙上开两个门。求从左边中点走到右边中点的最短距离。

分析:

以起点终点和每个门的两个端点建图,如果两个点可以直接相连(即不会被墙挡住),则权值为两点间的欧几里得距离。

然后求起点到终点的最短路即可。

  1. #include <cstdio>
  2. #include <cmath>
  3. #include <cstring>
  4. #include <vector>
  5. #include <algorithm>
  6. using namespace std;
  7.  
  8. const int maxn = ;
  9. const double INF = 1e4;
  10. const double eps = 1e-;
  11.  
  12. struct Point
  13. {
  14. double x, y;
  15. Point(double x=, double y=):x(x), y(y) {}
  16. }p[maxn * ];
  17.  
  18. typedef Point Vector;
  19.  
  20. Point read_point()
  21. {
  22. double x, y;
  23. scanf("%lf%lf", &x, &y);
  24. return Point(x, y);
  25. }
  26.  
  27. Point operator - (const Point& A, const Point& B)
  28. { return Point(A.x-B.x, A.y-B.y); }
  29.  
  30. Vector operator / (const Vector& A, double p)
  31. { return Vector(A.x/p, A.y/p); }
  32.  
  33. double Dot(const Vector& A, const Vector& B)
  34. { return A.x*B.x + A.y*B.y; }
  35.  
  36. double Length(const Vector& A)
  37. { return sqrt(Dot(A, A)); }
  38.  
  39. struct Door
  40. {
  41. double x, y1, y2, y3, y4;
  42. Door(double x=, double y1=, double y2=, double y3=, double y4=):x(x), y1(y1), y2(y2), y3(y3), y4(y4) {}
  43. };
  44.  
  45. vector<Door> door;
  46.  
  47. double d[maxn * ], w[maxn * ][maxn * ];
  48. bool vis[maxn * ];
  49. int cnt;
  50.  
  51. bool isOK(int a, int b)
  52. {//判断两点是否能直接到达
  53. if(p[a].x >= p[b].x) swap(a, b);
  54. for(int i = ; i < door.size(); ++i)
  55. {
  56. if(door[i].x <= p[a].x) continue;
  57. if(door[i].x >= p[b].x) break;
  58. double k = (p[b].y-p[a].y) / (p[b].x-p[a].x);
  59. double y = p[a].y + k * (door[i].x - p[a].x);
  60. if(!(y>=door[i].y1&&y<=door[i].y2 || y>=door[i].y3&&y<=door[i].y4)) return false;
  61. }
  62. return true;
  63. }
  64.  
  65. void Init()
  66. {
  67. for(int i = ; i < cnt; ++i)
  68. for(int j = i; j < cnt; ++j)
  69. if(i == j) w[i][j] = ;
  70. else w[i][j] = w[j][i] = INF;
  71. }
  72.  
  73. int main()
  74. {
  75. //freopen("in.txt", "r", stdin);
  76.  
  77. int n;
  78. while(scanf("%d", &n) == && n + )
  79. {
  80. door.clear();
  81. memset(vis, false, sizeof(vis));
  82. memset(d, , sizeof(d));
  83.  
  84. p[] = Point(, );
  85. cnt = ;
  86. for(int i = ; i < n; ++i)
  87. {
  88. double x, y[];
  89. scanf("%lf", &x);
  90. for(int j = ; j < ; ++j) { scanf("%lf", &y[j]); p[cnt++] = Point(x, y[j]); }
  91. door.push_back(Door(x, y[], y[], y[], y[]));
  92. }
  93. p[cnt++] = Point(, );
  94.  
  95. Init();
  96.  
  97. for(int i = ; i < cnt; ++i)
  98. for(int j = i+; j < cnt; ++j)
  99. {
  100. double l = Length(Vector(p[i]-p[j]));
  101. if(p[i].x == p[j].x) continue;
  102. if(isOK(i, j))
  103. w[i][j] = w[j][i] = l;
  104. }
  105. //Dijkstra
  106. d[] = ;
  107. for(int i = ; i < cnt; ++i) d[i] = INF;
  108. for(int i = ; i < cnt; ++i)
  109. {
  110. int x;
  111. double m = INF;
  112. for(int y = ; y < cnt; ++y) if(!vis[y] && d[y] <= m) m = d[x=y];
  113. vis[x] = ;
  114. for(int y = ; y < cnt; ++y) d[y] = min(d[y], d[x] + w[x][y]);
  115. }
  116.  
  117. printf("%.2f\n", d[cnt-]);
  118. }
  119.  
  120. return ;
  121. }

代码君

POJ (线段相交 最短路) The Doors的更多相关文章

  1. POJ_1556_The Doors_判断线段相交+最短路

    POJ_1556_The Doors_判断线段相交+最短路 Description You are to find the length of the shortest path through a ...

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

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

  3. POJ 1556 The Doors(线段相交+最短路)

    题目: Description You are to find the length of the shortest path through a chamber containing obstruc ...

  4. POJ 2556 (判断线段相交 + 最短路)

    题目: 传送门 题意:在一个左小角坐标为(0, 0),右上角坐标为(10, 10)的房间里,有 n 堵墙,每堵墙都有两个门.每堵墙的输入方式为 x, y1, y2, y3, y4,x 是墙的横坐标,第 ...

  5. POJ 1556 计算几何 判断线段相交 最短路

    题意: 在一个左下角坐标为(0,0),右上角坐标为(10,10)的矩形内,起点为(0,5),终点为(10,5),中间会有许多扇垂直于x轴的门,求从起点到终点在能走的情况下的最短距离. 分析: 既然是求 ...

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

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

  7. POJ 1556 The Doors(线段交+最短路)

    The Doors Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 5210   Accepted: 2124 Descrip ...

  8. POJ 1556 The Doors(线段交+最短路)

    #include <iostream> #include <stdio.h> #include <string.h> #include <algorithm& ...

  9. poj 1066 线段相交

    链接:http://poj.org/problem?id=1066 Treasure Hunt Time Limit: 1000MS   Memory Limit: 10000K Total Subm ...

随机推荐

  1. H264学习第一篇(编码结构分析)

    学习H264之前,最好阅读一下维基百科中有关H264的相关介绍,里面包含了其的发展历程.主要特点.参考文献.参考网站等. 研究H264的主要文件包括两份参考手册(一份是语法结构参考手册,一份是JM开发 ...

  2. Android开发中Eclipse里的智能提示设置

    今天开始学习一下Android开发,直接在Android Developers下载的一个开发工具包,然后再下了一个JDK,配置完环境变量等一系列的工作后环境就搭建好了,在新建好第一个Android项目 ...

  3. iOS中为网站添加图标到主屏幕以及增加启动画面

    虽然没有能力开发Native App,但还是可以利用iOS中Safari浏览器的特性小小的折腾一下,做一个伪Web App满足下小小的虚荣心的. 既然是在iOS中的Safari折腾的,那么代码中利用到 ...

  4. Mac技巧之让U盘、移动硬盘在苹果电脑和Windows PC都能识别/读写,且支持4GB大文件:exFAT格式

    如果您的 U 盘.移动硬盘既要用于 PC 又要用于苹果电脑,Mac OS X 系统的 HFS+ 和 Windows 的 NTFS 格式显然都不行……HFS+ 在 Windows 下不识别,NTFS 格 ...

  5. 如何应用CLR线程池来管理多线程

        class Program     {         static void Main(string[] args)         {             int intWorkerT ...

  6. WPF系列

    一.ListView绑定数据源XML //前端代码 1 <Window x:Class="ListView读取XML数据.MainWindow" xmlns="ht ...

  7. 【BZOJ3262】 陌上花开

    Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量.定义一朵花A比另一朵花B要美丽,当 ...

  8. Hadoop-2.2.0 + Hbase-0.96.2 + Hive-0.13.1(转)

    From:http://www.itnose.net/detail/6065872.html # 需要软件 Hadoop-2.2.0(目前Apache官网最新的Stable版本) Hbase-0.96 ...

  9. Windows下的Memcache安装与测试教程

    Windows下的Memcache安装 1.下载memcache for windows. 下载地址:http://splinedancer.com/memcached-win32/,推荐下载bina ...

  10. hdu 4648

    求一个数列中  去掉一些连续的数之后 不改变对m取余后的值 就是求一个最长的连续子序列 对m取余后为0 我的方法可能比较水 #include<iostream> #include<c ...