1066 -- Treasure Hunt

  题意是,在一个金字塔中有一个宝藏,金字塔里面有很多的墙,要穿过墙壁才能进入到宝藏所在的地方。可是因为某些原因,只能在两个墙壁的交点连线的中点穿过墙壁。问最少要穿过多少墙壁才能得到宝藏。

  比较容易想到的一个办法就是直接用中点构图,然后判断点与点之间是否能够直接相连,最后bfs得到最小距离。

  我的代码也是这样做,结果相当险的900+ms通过。

代码如下:

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <iostream>
  4. #include <algorithm>
  5. #include <cmath>
  6.  
  7. using namespace std;
  8.  
  9. const double EPS = 1e-;
  10. const int N = ;
  11. inline int sgn(double x) { return (x > EPS) - (x < -EPS);}
  12.  
  13. struct Point {
  14. double x, y;
  15. Point() {}
  16. Point(double x, double y) : x(x), y(y) {}
  17. bool operator < (Point a) const { return sgn(x - a.x) < || sgn(x - a.x) == && y < a.y;}
  18. bool operator == (Point a) const { return sgn(x - a.x) == && sgn(y - a.y) == ;}
  19. Point operator + (Point a) { return Point(x + a.x, y + a.y);}
  20. Point operator - (Point a) { return Point(x - a.x, y - a.y);}
  21. Point operator * (double p) { return Point(x * p, y * p);}
  22. Point operator / (double p) { return Point(x / p, y / p);}
  23. } ;
  24. inline double cross(Point a, Point b) { return a.x * b.y - a.y * b.x;}
  25. inline double dot(Point a, Point b) { return a.x * b.x + a.y * b.y;}
  26. inline double veclen(Point a) { return sqrt(dot(a, a));}
  27. inline Point vecunit(Point x) { return x / veclen(x);}
  28. inline Point normal(Point x) { return Point(-x.y, x.x) / veclen(x);}
  29. inline bool onseg(Point x, Point a, Point b) { return sgn(cross(a - x, b - x)) == && sgn(dot(a - x, b - x)) <= ;}
  30.  
  31. struct Line {
  32. Point s, t;
  33. Line() {}
  34. Line(Point s, Point t) : s(s), t(t) {}
  35. Point vec() { return t - s;}
  36. Point point(double p) { return s + vec() * p;}
  37. } ;
  38. inline bool onseg(Point x, Line l) { return onseg(x, l.s, l.t);}
  39. inline Point llint(Line a, Line b) { return a.point(cross(b.vec(), a.s - b.s) / cross(a.vec(), b.vec()));}
  40.  
  41. Point ips[N][N], trs, vex[N * N];
  42. bool out[N * N];
  43. int ipcnt[N], vexcnt;
  44. Line ls[N];
  45.  
  46. void input(int &n) {
  47. Point tmp[];
  48. for (int i = ; i < n; i++) {
  49. for (int j = ; j < ; j++) cin >> tmp[j].x >> tmp[j].y;
  50. ls[i] = Line(tmp[], tmp[]);
  51. }
  52. ls[n++] = Line(Point(0.0, 0.0), Point(100.0, 0.0));
  53. ls[n++] = Line(Point(100.0, 0.0), Point(100.0, 100.0));
  54. ls[n++] = Line(Point(100.0, 100.0), Point(0.0, 100.0));
  55. ls[n++] = Line(Point(0.0, 100.0), Point(0.0, 0.0));
  56. cin >> trs.x >> trs.y;
  57. }
  58.  
  59. inline Point mid(Point a, Point b) { return (a + b) / 2.0;}
  60.  
  61. int makevex(int n) {
  62. Point tmp;
  63. memset(ipcnt, , sizeof(ipcnt));
  64. for (int i = ; i < n; i++) {
  65. for (int j = ; j < i; j++) {
  66. if (sgn(cross(ls[i].vec(), ls[j].vec()))) {
  67. tmp = llint(ls[i], ls[j]);
  68. if (onseg(tmp, ls[i])) ips[i][ipcnt[i]++] = tmp;
  69. if (onseg(tmp, ls[j])) ips[j][ipcnt[j]++] = tmp;
  70. }
  71. }
  72. }
  73. vexcnt = ;
  74. vex[vexcnt++] = trs;
  75. memset(out, , sizeof(out));
  76. for (int i = ; i < n; i++) {
  77. ips[i][ipcnt[i]++] = ls[i].s;
  78. ips[i][ipcnt[i]++] = ls[i].t;
  79. sort(ips[i], ips[i] + ipcnt[i]);
  80. for (int j = ; j < ipcnt[i]; j++) {
  81. if (ips[i][j - ] == ips[i][j]) continue;
  82. vex[vexcnt++] = mid(ips[i][j - ], ips[i][j]);
  83. }
  84. }
  85. // cout << vexcnt << endl;
  86. for (int i = ; i < vexcnt; i++) {
  87. for (int j = n - ; j < n; j++) {
  88. if (onseg(vex[i], ls[j])) {
  89. out[i] = true;
  90. break;
  91. }
  92. }
  93. }
  94. // for (int i = 0; i < vexcnt; i++) cout << out[i]; cout << endl;
  95. return vexcnt;
  96. }
  97.  
  98. inline bool ssint(Line a, Line b) { return sgn(cross(a.s - b.s, a.t - b.s)) * sgn(cross(a.s - b.t, a.t - b.t)) <
  99. && sgn(cross(b.s - a.s, b.t - a.s)) * sgn(cross(b.s - a.t, b.t - a.t)) < ;}
  100.  
  101. bool mat[N * N][N * N];
  102.  
  103. bool test(int i, int j, int n) {
  104. Line tmp = Line(vex[i], vex[j]);
  105. for (int a = ; a < n; a++)
  106. if (onseg(vex[i], ls[a]) && onseg(vex[j], ls[a])) return false;
  107. for (int a = ; a < n; a++)
  108. if (ssint(tmp, ls[a])) return false;
  109. return true;
  110. }
  111.  
  112. void makemat(int n, int m) {
  113. memset(mat, , sizeof(mat));
  114. for (int i = ; i < n; i++) {
  115. for (int j = ; j < i; j++) {
  116. if (test(i, j, m)) mat[i][j] = mat[j][i] = true;
  117. }
  118. }
  119. // for (int i = 0; i < n; i++) {
  120. // for (int j = 0; j < n; j++) cout << mat[i][j]; cout << endl;
  121. // }
  122. }
  123.  
  124. int q[N * N * N];
  125. bool vis[N * N];
  126.  
  127. int bfs(int n) {
  128. int qh, qt;
  129. memset(vis, , sizeof(vis));
  130. qh = qt = ;
  131. q[qt++] = ;
  132. vis[] = true;
  133. int cnt = ;
  134. while (qh < qt) {
  135. int sz = qt - qh;
  136. cnt++;
  137. for (int i = ; i < sz; i++) {
  138. int cur = q[qh++];
  139. // cout << cur << endl;
  140. // cout << vex[cur].x << ' ' << vex[cur].y << endl;
  141. for (int j = ; j < n; j++) {
  142. if (vis[j] || !mat[cur][j]) continue;
  143. q[qt++] = j;
  144. vis[j] = true;
  145. if (out[j]) return cnt;
  146. }
  147. }
  148. }
  149. return -;
  150. }
  151.  
  152. int main() {
  153. // freopen("in", "r", stdin);
  154. int n;
  155. while (cin >> n) {
  156. input(n);
  157. int m;
  158. makemat(m = makevex(n), n);
  159. cout << "Number of doors = " << bfs(m) << endl;
  160. }
  161. return ;
  162. }

——written by Lyon

poj 1066 Treasure Hunt (Geometry + BFS)的更多相关文章

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

    Treasure Hunt Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 4797   Accepted: 1998 Des ...

  2. POJ 1066 Treasure Hunt(相交线段&amp;&amp;更改)

    Treasure Hunt 大意:在一个矩形区域内.有n条线段,线段的端点是在矩形边上的,有一个特殊点,问从这个点到矩形边的最少经过的线段条数最少的书目,穿越仅仅能在中点穿越. 思路:须要巧妙的转换一 ...

  3. POJ 1066 - Treasure Hunt - [枚举+判断线段相交]

    题目链接:http://poj.org/problem?id=1066 Time Limit: 1000MS Memory Limit: 10000K Description Archeologist ...

  4. poj 1066 Treasure Hunt

    http://poj.org/problem?id=1066 #include <cstdio> #include <cstring> #include <cmath&g ...

  5. POJ 1066 Treasure Hunt [想法题]

    题目链接: http://poj.org/problem?id=1066 --------------------------------------------------------------- ...

  6. POJ 1066 Treasure Hunt (线段相交)

    题意:给你一个100*100的正方形,再给你n条线(墙),保证线段一定在正方形内且端点在正方形边界(外墙),最后给你一个正方形内的点(保证不再墙上) 告诉你墙之间(包括外墙)围成了一些小房间,在小房间 ...

  7. POJ 1066 Treasure Hunt【线段相交】

    思路:枚举四边墙的门的中点,与终点连成一条线段,判断与其相交的线段的个数.最小的加一即为答案. 我是傻逼,一个数组越界调了两个小时. #include<stdio.h> #include& ...

  8. POJ 1066 Treasure Hunt --几何,线段相交

    题意: 正方形的房子,给一些墙,墙在区域内是封闭的,给你人的坐标,每穿过一道墙需要一把钥匙,问走出正方形需要多少把钥匙. 解法: 因为墙是封闭的,所以绕路也不会减少通过的墙的个数,还不如不绕路走直线, ...

  9. 简单几何(线段相交) POJ 1066 Treasure Hunt

    题目传送门 题意:从四面任意点出发,有若干障碍门,问最少要轰掉几扇门才能到达终点 分析:枚举入口点,也就是线段的两个端点,然后选取与其他线段相交点数最少的 + 1就是答案.特判一下n == 0的时候 ...

随机推荐

  1. Dijkstra,floyd,spfa三种最短路的区别和使用

    这里不列举三种算法的实现细节,只是简单描述下思想,分析下异同 一 Dijkstra Dijkstra算法可以解决无负权图的最短路径问题,只能应付单源起点的情况,算法要求两个集合,开始所有点在第二个集合 ...

  2. python的工具pip进行安装时出现 No module named 'pip'

    现象: 解决: python -m ensurepip easy_install pip python -m pip install --upgrade pip #用于更新pip,默认安装的是pip9 ...

  3. 2019阿里云开年Hi购季云通信分会场全攻略!

    2019阿里云云上Hi购季活动已经于2月25日正式开启,从已开放的活动页面来看,活动分为三个阶段: 2月25日-3月04日的活动报名阶段.3月04日-3月16日的新购满返+5折抢购阶段.3月16日-3 ...

  4. CSS-DOM的小知识(一)

    在DOM编程艺术中,CSS-DOM应用很广泛. 1.style属性 通过element.style.property可以获得元素的样式,但是style属性只能够返回内嵌样式,对于外部样式表的样式和he ...

  5. golang数组 排序和查找

    package main import "fmt" func BubbleSort(arr *[5]int){ fmt.Println("排序前arr=",(* ...

  6. 笔记:投机和投资 F4NNIU

    笔记:投机和投资 F4NNIU 投机是零和交易. 投资是正和博弈. 投机看是短期,只关心当下. 投资是看的长期,更关注未来. 投机容易分散注意力. 投资更关心交易外的注意力. 投机像是看运气,运气有好 ...

  7. Leetcode717.1-bit and 2-bit Characters1比特与2比特字符

    有两种特殊字符.第一种字符可以用一比特0来表示.第二种字符可以用两比特(10 或 11)来表示. 现给一个由若干比特组成的字符串.问最后一个字符是否必定为一个一比特字符.给定的字符串总是由0结束. 示 ...

  8. 为什么你应该使用OpenGL而不是DirectX?

    这是一篇很意思的博文,原文链接为:http://blog.wolfire.com/2010/01/Why-you-should-use-OpenGL-and-not-DirectX 大家可以思考一下: ...

  9. CentOS 上MySQL报错Can't connect to local Mysql server through socket '/tmp/mysql.scok' (111)

    好吧,这是最常见的MySQL服务没有打开 那就赶紧去打开啊! 在管理员模式下运行以下语句: /usr/local/mysql/bin/mysqld_safe --user=mysql & 成功 ...

  10. JMeter 参数意义

    样本数目:运行时得到的取样器响应结果个数 最新样本:最近一个取样器结果的响应时间 平均:所有取样器结果的响应时间平均值 偏离:所有取样器结果的响应时间标准差 吞吐量:每分钟响应的取样器结果个数 中值: ...