题意:给定一些线段障碍,判断怪物能不能逃离到无穷远处。

思路:从(0,0)点能否到无穷远处。用BFS搜索。那满足什么样的点符合要求,能加入到图中呢?

遍历每个点,显然一开始已经在某些线段上的点要删去。再判断,两点之间的连线是否与其他线段有交。有则删去。

这道题要注意如果两条线段重合,怎么办?延长每条线段,如果交点在线段内,不算。

  1. #include<cstdio>
  2. #include<cmath>
  3. #include<cstring>
  4. #include<algorithm>
  5. #include<iostream>
  6. #include<memory.h>
  7. #include<cstdlib>
  8. #include<vector>
  9. #define clc(a,b) memset(a,b,sizeof(a))
  10. #define LL long long int
  11. #define up(i,x,y) for(i=x;i<=y;i++)
  12. #define w(a) while(a)
  13. const double inf=0x3f3f3f3f;
  14. const int N = ;
  15. const double PI = acos(-1.0);
  16. using namespace std;
  17. const double eps = 1e-;
  18.  
  19. double dcmp(double x)
  20. {
  21. if(fabs(x) < eps) return ;
  22. else return x < ? - : ;
  23. }
  24.  
  25. struct Point
  26. {
  27. double x, y;
  28. Point(double x=, double y=):x(x),y(y) { }
  29. };
  30.  
  31. typedef Point Vector;
  32.  
  33. Vector operator + (const Point& A, const Point& B)
  34. {
  35. return Vector(A.x+B.x, A.y+B.y);
  36. }
  37.  
  38. Vector operator - (const Point& A, const Point& B)
  39. {
  40. return Vector(A.x-B.x, A.y-B.y);
  41. }
  42.  
  43. Vector operator * (const Point& A, double v)
  44. {
  45. return Vector(A.x*v, A.y*v);
  46. }
  47.  
  48. Vector operator / (const Point& A, double v)
  49. {
  50. return Vector(A.x/v, A.y/v);
  51. }
  52.  
  53. double Cross(const Vector& A, const Vector& B)
  54. {
  55. return A.x*B.y - A.y*B.x;
  56. }
  57.  
  58. double Dot(const Vector& A, const Vector& B)
  59. {
  60. return A.x*B.x + A.y*B.y;
  61. }
  62.  
  63. double Length(const Vector& A)
  64. {
  65. return sqrt(Dot(A,A));
  66. }
  67.  
  68. bool operator < (const Point& p1, const Point& p2)
  69. {
  70. return p1.x < p2.x || (p1.x == p2.x && p1.y < p2.y);
  71. }
  72.  
  73. bool operator == (const Point& p1, const Point& p2)
  74. {
  75. return p1.x == p2.x && p1.y == p2.y;
  76. }
  77.  
  78. bool SegmentProperIntersection(const Point& a1, const Point& a2, const Point& b1, const Point& b2)
  79. {
  80. double c1 = Cross(a2-a1,b1-a1), c2 = Cross(a2-a1,b2-a1),
  81. c3 = Cross(b2-b1,a1-b1), c4=Cross(b2-b1,a2-b1);
  82. return dcmp(c1)*dcmp(c2)< && dcmp(c3)*dcmp(c4)<;
  83. }
  84.  
  85. bool OnSegment(const Point& p, const Point& a1, const Point& a2)
  86. {
  87. return dcmp(Cross(a1-p, a2-p)) == && dcmp(Dot(a1-p, a2-p)) < ;
  88. }
  89.  
  90. const int maxv = + ;
  91. int V;
  92. int G[maxv][maxv], vis[maxv];
  93.  
  94. bool dfs(int u)
  95. {
  96. if(u == ) return true; // 1是终点
  97. vis[u] = ;
  98. for(int v = ; v < V; v++)
  99. if(G[u][v] && !vis[v] && dfs(v)) return true;
  100. return false;
  101. }
  102.  
  103. const int maxn = + ;
  104. int n;
  105. Point p1[maxn], p2[maxn];
  106.  
  107. // 在任何一条线段的中间(在端点不算)
  108. bool OnAnySegment(Point p)
  109. {
  110. for(int i = ; i < n; i++)
  111. if(OnSegment(p, p1[i], p2[i])) return true;
  112. return false;
  113. }
  114.  
  115. // 与任何一条线段规范相交
  116. bool IntersectWithAnySegment(Point a, Point b)
  117. {
  118. for(int i = ; i < n; i++)
  119. if(SegmentProperIntersection(a, b, p1[i], p2[i])) return true;
  120. return false;
  121. }
  122.  
  123. bool find_path()
  124. {
  125. // 构图
  126. vector<Point> vertices;
  127. vertices.push_back(Point(, )); // 起点
  128. vertices.push_back(Point(1e5, 1e5)); // 终点
  129. for(int i = ; i < n; i++)
  130. {
  131. if(!OnAnySegment(p1[i])) vertices.push_back(p1[i]);
  132. if(!OnAnySegment(p2[i])) vertices.push_back(p2[i]);
  133. }
  134. V = vertices.size();
  135. memset(G, , sizeof(G));
  136. memset(vis, , sizeof(vis));
  137. for(int i = ; i < V; i++)
  138. for(int j = i+; j < V; j++)
  139. if(!IntersectWithAnySegment(vertices[i], vertices[j]))
  140. G[i][j] = G[j][i] = ;
  141. return dfs();
  142. }
  143.  
  144. int main()
  145. {
  146. while(cin >> n && n)
  147. {
  148. for(int i = ; i < n; i++)
  149. {
  150. double x1, y1, x2, y2;
  151. cin >> x1 >> y1 >> x2 >> y2;
  152. Point a = Point(x1, y1);
  153. Point b = Point(x2, y2);
  154. Vector v = b - a;
  155. v = v / Length(v);
  156. p1[i] = a + v * 1e-;
  157. p2[i] = b + v * 1e-;
  158. }
  159. if(find_path()) cout << "no\n";
  160. else cout << "yes\n";
  161. }
  162. return ;
  163. }

uvalive 2797 Monster Trap的更多相关文章

  1. LA 2797 (平面直线图PLSG) Monster Trap

    题意: 平面上有n条线段,一次给出这n条线段的两个端点的坐标.问怪兽能否从坐标原点逃到无穷远处.(两直线最多有一个交点,且没有三线共交点的情况) 分析: 首先说明一下线段的规范相交:就是交点唯一而且在 ...

  2. LA2797 Monster Trap

    题意 PDF 分析 可以考虑建图,跑迷宫. 然后以线段端点,原点,和无穷大点建图,有边的条件是两点连线和墙没有交点. 但是对两个线段的交点处理就会有问题,所以把线段延长.另外还需要判断延长后在墙上,舍 ...

  3. [GodLove]Wine93 Tarining Round #10

    比赛链接: http://www.bnuoj.com/v3/contest_show.php?cid=4159 题目来源: lrj训练指南---几何算法 Flag ID Title   A Board ...

  4. UVALive - 4108 SKYLINE[线段树]

    UVALive - 4108 SKYLINE Time Limit: 3000MS     64bit IO Format: %lld & %llu Submit Status uDebug ...

  5. UVALive - 3942 Remember the Word[树状数组]

    UVALive - 3942 Remember the Word A potentiometer, or potmeter for short, is an electronic device wit ...

  6. UVALive - 3942 Remember the Word[Trie DP]

    UVALive - 3942 Remember the Word Neal is very curious about combinatorial problems, and now here com ...

  7. linux shell trap的使用

    原文地址:http://blog.sina.com.cn/s/blog_62eb16bb01014dbh.html 一. trap捕捉到信号之后,可以有三种反应方式: (1)执行一段程序来处理这一信号 ...

  8. Alignment trap 解决方法  【转 结合上一篇

    前几天交叉编译crtmpserver到arm9下.编译通过,但是运行的时候,总是提示Alignment trap,但是并不影响程序的运行.这依然很令人不爽,因为不知道是什么原因引起的,这就像一颗定时炸 ...

  9. ARMLinux下Alignment trap的一些测试 【转自 李迟的专栏 CSDN http://blog.csdn.net/subfate/article/details/7847356

    项目中有时会遇到字节对齐的问题,英文为“Alignment trap”,如果直译,意思为“对齐陷阱”,不过这个说法不太好理解,还是直接用英文来表达. ARM平台下一般是4字节对齐,可以参考文后的给出的 ...

随机推荐

  1. c#带参数和返回值的函数 开启线程调用的方法

    public delegate string DgTest(); private void btn_District_Click(object sender, EventArgs e) { //实例化 ...

  2. smarty 时间格式化date_format

    代码如下:$smarty = new Smarty; $smarty->assign('yesterday', strtotime('-1 day')); $smarty->display ...

  3. hdu 3449

    有依赖的背包,转化成01背包来做: #include<iostream> #include<cstdio> #include<cstring> #include&l ...

  4. OneAPM 技术公开课:北京,北京!

    随着互联网行业的高速发展,数据库已经是绝大多数 IT 应用的核心因素,虽然数据库种类繁多,但是多层体系结构以及 SOA 的发展,使得应用逻辑的实现前移.数据库的性能与其功能相比较,变得越来越重要了. ...

  5. C/C++中几种经典的垃圾回收算法

    1.引用计数算法 引用计数(Reference Counting)算法是每个对象计算指向它的指针的数量,当有一个指针指向自己时计数值加1:当删除一个指向自己的指针时,计数值减1,如果计数值减为0,说明 ...

  6. nginx做负载均衡配置文件

    nginx做负载均衡是在反向代理的基础上做的,代码如下: ## Basic reverse proxy server ## ## Apache backend for www.baidu.com ## ...

  7. iOS开发--绘图教程

    本文是<Programming iOS5>中Drawing一章的翻译,考虑到主题完整性,翻译版本中加入了一些书中未涉及到的内容.希望本文能够对你有所帮助. 本文由海水的味道翻译整理,转载请 ...

  8. 当当开源sharding-jdbc,轻量级数据库分库分表中间件

    近期,当当开源了数据库分库分表中间件sharding-jdbc. Sharding-JDBC是当当应用框架ddframe中,从关系型数据库模块dd-rdb中分离出来的数据库水平分片框架,实现透明化数据 ...

  9. &&运算符和||运算符的优先级问题

    package priority; public class TestAndOrPriority { /* * &&的优先级高就不代表 他会先运行 ||的右边 而是说会把右边用& ...

  10. IL指令集(转)

    名称 说明 Add 将两个值相加并将结果推送到计算堆栈上. Add.Ovf 将两个整数相加,执行溢出检查,并且将结果推送到计算堆栈上. Add.Ovf.Un 将两个无符号整数值相加,执行溢出检查,并且 ...