POJ3072:Robot

——url:

——problem:二维平面上有N个点,求从1到N的最短时间,转向需要时间,每度一秒。

——solution:二维DIJKSTRA,DIST[I][J]表示起点到I的最短时间,I的前驱为J,用来计算转向时间。

注意:

1、转向角度<=180度。

2、用atan2比atan好,atan2值域范围-pi到pi。

3、计算转向角:

     例如:由P1经过P2到P3

        angle=fabs(atan2(p2.y-p1.y,p2.x-p1.x)【P2-P1向量的方向角】- atan2(p3.y-p2.y,p3.x-p2.x)【P3-P2向量的方向角】)

————————————————————————————————————————————————————————————

View Code
1 #include<stdio.h>
2 #include<math.h>
3 #include<memory.h>
4 #include<queue>
5  using namespace std;
6  #define eps 1e-8
7  #define oo 0xfffffff
8 #define P 180.0/acos(-1.0)
9 #define V 100
10 int i, j, n, r;
11 double ans;
12 double L[V][V], dist[V][V], from[V];
13 bool vis[V];
14 struct
15 {
16 double x, y;
17 } N[V];
18 struct node
19 {
20 int u;
21 double ang, l;
22 friend bool operator <(node a, node b)
23 {
24 return a.l > b.l;
25 }
26 } x, y;
27 double dis(double x1, double y1, double x2, double y2)
28 {
29 return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
30 }
31 double angle(int p1, int p2)
32 {
33 return atan2((N[p2].y - N[p1].y),(N[p2].x - N[p1].x)); ATAN2()值域为(-PI,PI)
34 }
35 double dijkstra()
36 {
37 int i, j;
38 double ang;
39 priority_queue<node> q;
40 for (i = 0; i < n; i++)
41 for (j = 0; j < n; j++)
42 dist[i][j] = oo;
43 memset(vis, 0, sizeof(vis));
44 x.u=0;
45 x.l=0.0;
46 x.ang=angle(0,n-1);
47 q.push(x);
48 while (!q.empty())
49 {
50 x = q.top();
51 q.pop();
52 if (x.u == n - 1)
53 return x.l;
54 for (i = 0; i < n; i++)
55 if (i != x.u)
56 {
57 ang = fabs(x.ang - angle(x.u, i)) * P;
58 if (ang - eps > 180.0) //超过180的话要处理
59 ang = 360 - ang;
60 if (L[x.u][i] + eps < r && L[x.u][i] + x.l + ang < dist[i][x.u])
61 {
62 y.u = i;
63 y.l = L[x.u][i] + x.l + ang;
64 y.ang = angle(x.u, i);
65 dist[y.u][x.u] = y.l;
66 q.push(y);
67 }
68 }
69 }
70 return -1;
71 }
72 int main()
73 {
74 while (scanf("%d%d", &r, &n) && (n != -1))
75 {
76 for (i = 0; i < n; i++)
77 scanf("%lf%lf", &N[i].x, &N[i].y);
78 for (i = 0; i < n; i++)
79 for (j = 0; j < n; j++)
80 L[i][j] = dis(N[i].x, N[i].y, N[j].x, N[j].y);
81 ans = dijkstra();
82 if (ans < 0)
83 printf("impossible\n");
84 else
85 printf("%.0lf\n", ans);
86 }
87 return 0;
88 }
posted on 2011-03-20 21:52  风也轻云也淡  阅读(262)  评论(0编辑  收藏  举报