poj1066Treasure Hunt(线段相交)

链接

很纠结的找到了所有线段的中点,又很纠结的找到了哪些中点可以直接相连,最后bfs一下求出了最短路。。

  1 #include <iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<stdlib.h>
  6 #include<vector>
  7 #include<cmath>
  8 #include<queue>
  9 #include<set>
 10 using namespace std;
 11 #define N 2210
 12 #define LL long long
 13 #define INF 0xfffffff
 14 const double eps = 1e-10;
 15 const double inf = ~0u>>2;
 16 vector<int>ed[N];
 17 struct Point
 18 {
 19     double x,y;
 20     Point(double x=0,double y=0):x(x),y(y) {} //构造函数 方便代码编写
 21 } p[105],q[N];
 22 int g,dis[N];
 23 bool vis[N];
 24 vector<Point>pi[N];
 25 typedef Point pointt;
 26 pointt operator + (Point a,Point b)
 27 {
 28     return Point(a.x+b.x,a.y+b.y);
 29 }
 30 pointt operator - (Point a,Point b)
 31 {
 32     return Point(a.x-b.x,a.y-b.y);
 33 }
 34 pointt operator * (Point a,double b)
 35 {
 36     return Point(a.x*b,a.y*b);
 37 }
 38 pointt operator / (Point a,double b)
 39 {
 40     return Point(a.x/b,a.y/b);
 41 }
 42 bool operator < (const Point &a,const Point &b)
 43 {
 44     return a.x<b.x||(a.x==b.x&&a.y<b.y);
 45 }
 46 int dcmp(double x)
 47 {
 48     if(fabs(x)<eps) return 0;
 49     else return x<0?-1:1;
 50 }
 51 double cross(Point a,Point b)
 52 {
 53     return a.x*b.y-a.y*b.x;
 54 }
 55 Point intersection1(Point a,Point b,Point c,Point d)//直线交点求解
 56 {
 57     Point pp = a;
 58     double t = ((a.x-c.x)*(c.y-d.y)-(a.y-c.y)*(c.x-d.x))/
 59                ((a.x-b.x)*(c.y-d.y)-(a.y-b.y)*(c.x-d.x));
 60     pp.x+=(b.x-a.x)*t;
 61     pp.y+=(b.y-a.y)*t;
 62     return pp;
 63 }
 64 bool seginter(pointt a1,pointt a2,pointt b1,pointt b2)
 65 {
 66     double c1 = cross(a2-a1,b1-a1),c2 = cross(a2-a1,b2-a1),
 67                                         c3 = cross(b2-b1,a1-b1),c4 = cross(b2-b1,a2-b1);
 68     return dcmp(c1)*dcmp(c2)<0&&dcmp(c3)*dcmp(c4)<0;
 69 }
 70 void init(int i,int n)
 71 {
 72     p[i+1].x = 0;
 73     p[i+1].y = 0;
 74     p[i+2].x = 0;
 75     p[i+2].y = 100;
 76     p[i+3].x = 100;
 77     p[i+3].y = 100;
 78     p[i+4].x = 100;
 79     p[i+4].y = 0;
 80     p[i+1+n] = p[i+2];
 81     p[i+2+n] = p[i+3];
 82     p[i+3+n] = p[i+4];
 83     p[i+4+n] = p[i+1];
 84 
 85 }
 86 int judge(int x)
 87 {
 88     if(fabs(q[x].x)<eps||fabs(q[x].y)<eps||fabs(q[x].x-100.0)<eps||fabs(q[x].y-100.0)<eps)
 89         return 1;
 90     return 0;
 91 }
 92 void bfs(int st)
 93 {
 94     queue<int>Q;
 95     Q.push(st);
 96     memset(vis,0,sizeof(vis));
 97    // cut<<
 98     for(int i = 0 ; i <= st ; i++)
 99         dis[i] = INF;
100     dis[st] = 0;
101     while(!Q.empty())
102     {
103         int u = Q.front();
104         Q.pop();
105         //printf("%.2f %.2f %d
",q[u].x,q[u].y,dis[u]);
106         if(judge(u))
107         {
108             printf("Number of doors = %d
",dis[u]);
109             break;
110         }
111         for(int i =0 ; i < ed[u].size() ; i++)
112         {
113             int v = ed[u][i];
114             //cout<<v<<" "<<dis[u]<<endl;
115             dis[v] = min(dis[v],dis[u]+1);
116             if(!vis[v])
117             {
118                 vis[v] = 1;
119                 Q.push(v);
120             }
121         }
122     }
123 }
124 bool cmp(Point a,Point b)
125 {
126     if(fabs(a.x-b.x)<eps)
127         return a.y<b.y;
128     return a.x<b.x;
129 }
130 int main()
131 {
132     int n,i,j,e;
133     scanf("%d",&n);
134 //    while(scanf("%d",&n)!=EOF)
135 //    {
136         n+=4;
137         g = 0;
138         for(i = 1; i <= n-4 ; i++)
139         {
140             scanf("%lf%lf%lf%lf",&p[i].x,&p[i].y,&p[i+n].x,&p[i+n].y);
141         }
142         init(n-4,n);
143         for(i = 1; i <= n-4; i++)
144         {
145             for(j = 1; j <= n-4 ; j++)
146             {
147                 if(i==j) continue;
148                 if(seginter(p[i],p[i+n],p[j],p[j+n]))
149                 {
150                     pi[i].push_back(intersection1(p[i],p[i+n],p[j],p[j+n]));
151                 }
152             }
153         }
154         for(i = 1 ; i <= n-4 ; i++)
155         {
156             if(dcmp(p[i].x)==0)
157                 pi[n-3].push_back(p[i]);
158             if(dcmp(p[i+n].x)==0)
159                 pi[n-3].push_back(p[i+n]);
160             if(dcmp(p[i].y-100)==0)
161                 pi[n-2].push_back(p[i]);
162             if(dcmp(p[i+n].y-100)==0)
163                 pi[n-2].push_back(p[i+n]);
164             if(dcmp(p[i].x-100)==0)
165                 pi[n-1].push_back(p[i]);
166             if(dcmp(p[i+n].x-100)==0)
167                 pi[n-1].push_back(p[i+n]);
168             if(dcmp(p[i].y)==0)
169                 pi[n].push_back(p[i]);
170             if(dcmp(p[i+n].y)==0)
171                 pi[n].push_back(p[i+n]);
172         }
173         for(i = 1 ; i <= n; i++)
174         {
175             pi[i].push_back(p[i]);
176             pi[i].push_back(p[i+n]);
177             sort(pi[i].begin(),pi[i].end(),cmp);
178             for(j = 0 ; j < pi[i].size()-1 ; j++)
179             {
180                 Point tp;
181                 Point p1 = pi[i][j],p2= pi[i][j+1];
182                 if(dcmp(p1.x-p2.x)==0&&dcmp(p1.y-p2.y)==0) continue;
183                 tp.x = (p1.x+p2.x)/2;
184                 tp.y = (p1.y+p2.y)/2;
185                 // printf("%d tpx = %.2f tpy = %.2f p1x = %.2f p1y = %.2f p2x = %.2f p2y = %.2f
",i,tp.x,tp.y,p1.x,p1.y,p2.x,p2.y);
186                 q[++g] = tp;
187             }
188             pi[i].clear();
189         }
190         g++;
191         scanf("%lf%lf",&q[g].x,&q[g].y);
192         for(i = 1; i <= g ; i++)
193             ed[i].clear();
194         for(i = 1; i <= g ; i++)
195         {
196             //  printf("%.2f %.2f
",q[i].x,q[i].y);
197             for(j = 1; j <= g ; j++)
198             {
199                 if(i==j) continue;
200                 for(e = 1; e <= n; e++)
201                 {
202                     if(seginter(q[i],q[j],p[e],p[e+n]))
203                     {
204 //                        if(i==g)
205 //                        printf("%.2f %.2f e = %d
",q[j].x,q[j].y,e);
206                         break;
207                     }
208                 }
209                 if(e>n)
210                 {
211 //                    if(i==g)
212 //                    printf("%.2f %.2f %.2f %.2f
",q[i].x,q[i].y,q[j].x,q[j].y);
213                     ed[i].push_back(j);
214                 }
215             }
216         }
217         bfs(g);
218 //    }
219     return 0;
220 }
View Code

感觉这题没那么复杂,交对后搜了下题解,,然后 这题是一个水题,确实水。。

因为这个点的最终目的是要走出去的,边界上墙的点相对于边界上其它的点应该是更优的,所以只需枚举这些点到达起点经过多少堵墙即可。

几何抓不住重点是件很纠结的事。

附优美的简短的跑得飞快的代码

 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<stdlib.h>
 6 #include<vector>
 7 #include<cmath>
 8 #include<queue>
 9 #include<set>
10 using namespace std;
11 #define N 2210
12 #define LL long long
13 #define INF 0xfffffff
14 const double eps = 1e-10;
15 const double inf = ~0u>>2;
16 vector<int>ed[N];
17 struct Point
18 {
19     double x,y;
20     Point(double x=0,double y=0):x(x),y(y) {} //构造函数 方便代码编写
21 } p[105],q[N];
22 int g,dis[N];
23 bool vis[N];
24 vector<Point>pi[N];
25 typedef Point pointt;
26 pointt operator + (Point a,Point b)
27 {
28     return Point(a.x+b.x,a.y+b.y);
29 }
30 pointt operator - (Point a,Point b)
31 {
32     return Point(a.x-b.x,a.y-b.y);
33 }
34 pointt operator * (Point a,double b)
35 {
36     return Point(a.x*b,a.y*b);
37 }
38 pointt operator / (Point a,double b)
39 {
40     return Point(a.x/b,a.y/b);
41 }
42 bool operator < (const Point &a,const Point &b)
43 {
44     return a.x<b.x||(a.x==b.x&&a.y<b.y);
45 }
46 int dcmp(double x)
47 {
48     if(fabs(x)<eps) return 0;
49     else return x<0?-1:1;
50 }
51 double cross(Point a,Point b)
52 {
53     return a.x*b.y-a.y*b.x;
54 }
55 bool seginter(pointt a1,pointt a2,pointt b1,pointt b2)
56 {
57     double c1 = cross(a2-a1,b1-a1),c2 = cross(a2-a1,b2-a1),
58                                         c3 = cross(b2-b1,a1-b1),c4 = cross(b2-b1,a2-b1);
59     return dcmp(c1)*dcmp(c2)<0&&dcmp(c3)*dcmp(c4)<0;
60 }
61 int main()
62 {
63     int n,i,j,e;
64     scanf("%d",&n);
65     g = 0;
66     for(i = 1; i <= n ; i++)
67     {
68         scanf("%lf%lf%lf%lf",&p[i].x,&p[i].y,&p[i+n].x,&p[i+n].y);
69     }
70     Point tp;
71     scanf("%lf%lf",&tp.x,&tp.y);
72     if(n==0)
73     {
74         puts("Number of doors = 1");
75         return 0;
76     }
77     int ans = INF;
78     for(i = 1 ; i <= n*2; i++)
79     {
80         int ts = 1;
81         for(j = 1 ; j <= n ; j++)
82         {
83             if(seginter(p[i],tp,p[j],p[j+n]))
84                 ts++;
85         }
86         ans = min(ans,ts);
87     }
88     printf("Number of doors = %d
",ans);
89     return 0;
90 }
View Code
原文地址:https://www.cnblogs.com/shangyu/p/3804512.html