uvalive 2797 Monster Trap

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

思路:从(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 = 4010;
 15 const double PI = acos(-1.0);
 16 using namespace std;
 17 const double eps = 1e-12;
 18 
 19 double dcmp(double x)
 20 {
 21     if(fabs(x) < eps) return 0;
 22     else return x < 0 ? -1 : 1;
 23 }
 24 
 25 struct Point
 26 {
 27     double x, y;
 28     Point(double x=0, double y=0):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)<0 && dcmp(c3)*dcmp(c4)<0;
 83 }
 84 
 85 bool OnSegment(const Point& p, const Point& a1, const Point& a2)
 86 {
 87     return dcmp(Cross(a1-p, a2-p)) == 0 && dcmp(Dot(a1-p, a2-p)) < 0;
 88 }
 89 
 90 const int maxv = 200 + 5;
 91 int V;
 92 int G[maxv][maxv], vis[maxv];
 93 
 94 bool dfs(int u)
 95 {
 96     if(u == 1) return true; // 1是终点
 97     vis[u] = 1;
 98     for(int v = 0; v < V; v++)
 99         if(G[u][v] && !vis[v] && dfs(v)) return true;
100     return false;
101 }
102 
103 const int maxn = 100 + 5;
104 int n;
105 Point p1[maxn], p2[maxn];
106 
107 // 在任何一条线段的中间(在端点不算)
108 bool OnAnySegment(Point p)
109 {
110     for(int i = 0; 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 = 0; 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(0, 0)); // 起点
128     vertices.push_back(Point(1e5, 1e5)); // 终点
129     for(int i = 0; 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, 0, sizeof(G));
136     memset(vis, 0, sizeof(vis));
137     for(int i = 0; i < V; i++)
138         for(int j = i+1; j < V; j++)
139             if(!IntersectWithAnySegment(vertices[i], vertices[j]))
140                 G[i][j] = G[j][i] = 1;
141     return dfs(0);
142 }
143 
144 int main()
145 {
146     while(cin >> n && n)
147     {
148         for(int i = 0; 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-6;
157             p2[i] = b + v * 1e-6;
158         }
159         if(find_path()) cout << "no\n";
160         else cout << "yes\n";
161     }
162     return 0;
163 }
View Code

 

posted @ 2015-10-19 22:16  yyblues  阅读(272)  评论(0编辑  收藏  举报