蜗牛の狂奔笔记
对于蜗牛来说,狂奔虽不代表极速,但展现的却是一种拼尽全力的姿态........
pku 3072
2009年7月26日
题目链接:
PKU 3072 Robot
分类:角度旋转+Dijkastra
题目分析与算法原型
此题也算是最短路的一个变形,计算代价的时候加入了每3个点,两条边的夹角的度数,因此需要自己好好的推算一下角度的公式,题目已经提示了用atan2(double,double)这个函数,所以计算的时候把握好3个点中以哪个点为旋转点,关于旋转可以有两个方向,取小于180度的那个方向
Code:
1
#include
<
stdio.h
>
2
#include
<
string
.h
>
3
#include
<
math.h
>
4
#define
max 1000000000
5
#define
len 25
6
#define
pi acos(-1.0)
7
8
int
r,n,visit[len],path[len];
9
double
x[len],y[len],map[len][len],dis[len];
10
bool
find;
11
12
void
init()
13
{
14
int
i,j;
15
for
(i
=
1
;i
<=
n;i
++
)
16
for
(j
=
1
;j
<=
n;j
++
)
17
{
18
if
(i
==
j)map[i][j]
=
0
;
19
else
20
{
21
double
l
=
sqrt((x[i]
-
x[j])
*
(x[i]
-
x[j])
+
(y[i]
-
y[j])
*
(y[i]
-
y[j]));
22
if
(l
>
r)map[i][j]
=
max;
23
else
map[i][j]
=
l;
24
}
25
}
26
}
27
double
degree(
int
start,
int
mid,
int
end,
bool
change)
28
{
29
double
ds,d1,d2;
30
31
if
(
!
change)d1
=
atan2(y[mid]
-
y[start],x[mid]
-
x[start])
*
180
/
pi;
32
else
d1
=
atan2(y[start]
-
y[mid],x[start]
-
x[mid])
*
180
/
pi;
33
d2
=
atan2(y[end]
-
y[mid],x[end]
-
x[mid])
*
180
/
pi;
34
if
(d1
<
0
)d1
+=
360
;
35
if
(d2
<
0
)d2
+=
360
;
36
ds
=
fabs(d2
-
d1);
37
if
(ds
>
180
)ds
=
360
-
ds;
38
return
ds;
39
}
40
void
dij(
int
v0,
int
v)
41
{
42
int
i,j,u;
43
for
(i
=
1
;i
<
n;i
++
)
44
{
45
if
(i
!=
v0
&&
map[v0][i]
<
max)
46
{
47
double
t
=
degree(n,v0,i,
true
);
48
dis[i]
=
map[v0][i]
+
t;
49
}
50
else
dis[i]
=
map[v0][i];
51
52
if
(i
!=
v0
&&
dis[i]
<
max)path[i]
=
v0;
53
else
path[i]
=-
1
;
54
}
55
dis[n]
=
map[v0][n];
56
visit[v0]
=
1
;
57
for
(i
=
1
;i
<
n;i
++
)
58
{
59
double
min
=
max;
60
for
(j
=
1
;j
<=
n;j
++
)
61
if
(
!
visit[j]
&&
dis[j]
<
min)
62
{
63
u
=
j;
64
min
=
dis[j];
65
}
66
if
(min
==
max)
return
;
67
68
if
(u
==
v)
69
{
70
find
=
true
;
71
return
;
72
}
73
visit[u]
=
1
;
74
for
(j
=
1
;j
<=
n;j
++
)
75
if
(
!
visit[j]
&&
map[u][j]
<
max)
76
{
77
double
tt
=
degree(path[u],u,j,
false
);
78
if
(dis[u]
+
map[u][j]
+
tt
<
dis[j])
79
{
80
dis[j]
=
dis[u]
+
map[u][j]
+
tt;
81
path[j]
=
u;
82
}
83
}
84
}
85
return
;
86
}
87
88
int
main()
89
{
90
int
i;
91
while
(scanf(
"
%d%d
"
,
&
r,
&
n)
!=
EOF)
92
{
93
if
(r
==-
1
&&
n
==-
1
)
break
;
94
for
(i
=
1
;i
<=
n;i
++
)scanf(
"
%lf%lf
"
,
&
x[i],
&
y[i]);
95
find
=
false
;
96
init();
97
memset(visit,
0
,
sizeof
(visit));
98
dij(
1
,n);
99
if
(find)printf(
"
%d\n
"
,(
int
)(dis[n]
+
0.5
));
100
else
printf(
"
impossible\n
"
);
101
}
102
return
0
;
103
}
104
posted on 2009-07-26 17:49
蜗牛也Coding
阅读(243)
评论(0)
编辑
收藏
引用
只有注册用户
登录
后才能发表评论。
【推荐】100%开源!大型工业跨平台软件C++源码提供,建模,组态!
网站导航:
博客园
IT新闻
BlogJava
知识库
博问
管理
Powered by:
C++博客
Copyright © 蜗牛也Coding
<
2009年7月
>
日
一
二
三
四
五
六
28
29
30
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
6
7
8
导航
C++博客
首页
新随笔
联系
聚合
管理
统计
随笔 - 78
文章 - 0
评论 - 96
引用 - 0
常用链接
我的随笔
我的评论
我参与的随笔
留言簿
(8)
给我留言
查看公开留言
查看私人留言
随笔档案
(78)
2011年7月 (1)
2011年4月 (1)
2010年11月 (4)
2010年10月 (4)
2010年9月 (2)
2010年8月 (7)
2010年3月 (1)
2010年2月 (5)
2009年12月 (2)
2009年10月 (1)
2009年9月 (1)
2009年8月 (16)
2009年7月 (31)
2009年6月 (2)
搜索
积分与排名
积分 - 92566
排名 - 258
最新评论
1. re: 关于 OpenGl
太谢谢了。
--袁锋
2. re: 关于 OpenGl
太感谢!
--芙
3. re: 关于MAC系统win 7虚拟机不能上网的问题[未登录]
.vmx文件在哪里?
--a
4. re: MFC中如何将 CFormView放置到一个CDockablePane中
注释掉的创建部分,指针调用
为何不用友元类声明下,就可以用了的。CreateOne,有点绕。
感谢博主分享。
--ren
5. re: 关于 OpenGl
非常感谢~~
--无叶莲
阅读排行榜
1. pragma comment的使用(转)(17211)
2. MFC中如何将 CFormView放置到一个CDockablePane中(8221)
3. (转)关于OpenGL的安装(4830)
4. 关于 OpenGl(4426)
5. VC 界面窗口,静态分割后如何锁定分隔条或限制分隔条的移动范围(4298)
评论排行榜
1. 据说是来自chrome的代码里的一个模板(13)
2. 关于 OpenGl(10)
3. Visual Studio 历史简介(转)(6)
4. pku 1200(6)
5. VC 界面窗口,静态分割后如何锁定分隔条或限制分隔条的移动范围(5)