码迷,mamicode.com
首页 > 其他好文 > 详细

例题解释A*

时间:2015-09-03 21:35:22      阅读:265      评论:0      收藏:0      [点我收藏+]

标签:

题目链接:

http://poj.org/problem?id=2243

题目意思很简单,一个8*8的棋盘,给定两个点的坐标,问国际象棋里面的骑士从一个点走到另一个点所需要的最小步数。走的方式就是类似于中国象棋里面的马,八个方位。

一般就会直接使用BFS搜了,8*8直接搜也不会爆,现在看下使用A*。

A*的关键是怎么选取一个合适的h(x),那就是需要保证:h( x ) <= d( x, y ) + h( y ),至于原因,参见:http://www.cnblogs.com/be-saber/p/4780564.html

对于一步的走法,那就是一个“日”字了。

这时我们就可以选择 欧几里得距离, 可以发现, h( x ), d(x, y), h(y)就是三角形的三边(可能三点共线)了,那么上述条件是肯定满足的了。

代码如下:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<queue>
 4 #include<cmath>
 5 #include<algorithm>
 6 #include<cstring>
 7 using namespace std ;
 8 
 9 #define POS pair<int, int>
10 const int MAXM = 10 ;
11 //h(x)取欧几里得距离
12 POS s, t ;
13 bool vis[MAXM][MAXM] ;
14 float gx[MAXM][MAXM] ;
15 int step[MAXM][MAXM] ;
16 int dir[8][2] = {{1, 2}, {1, -2}, {-1, 2}, {-1, -2}, {2, 1}, {2, -1}, {-2, 1}, {-2, -1}} ;
17 //
18 bool judge(POS x){
19     if( x.first < 1 || x.first > 8 || x.second < 1 || x.second > 8 )    return false ;
20     return true ;
21 }
22 //
23 float calDis(POS x, POS y){
24     return sqrt((x.first-y.first)*(x.first-y.first)+(x.second-y.second)*(x.second-y.second)) ;
25 }
26 //
27 int solve(){
28     memset(vis, false, sizeof(vis)) ;
29     memset(gx, 0, sizeof(gx)) ;
30     memset(step, 0, sizeof(step)) ;
31     priority_queue< pair<float, POS> > heap ;
32     while( !heap.empty() )    heap.pop() ;
33     heap.push(make_pair(-calDis(s, t), s)) ;
34     gx[s.first][s.second] = 0 ;
35     while( !heap.empty() ){
36         int val = heap.top().first ;
37         POS x = heap.top().second ;
38         heap.pop() ;
39         vis[x.first][x.second] = true ;
40         if( x.first == t.first && x.second == t.second ){
41             return step[x.first][x.second] ;
42         }
43         for( int i = 0; i < 8; i++ ){
44             POS u ;
45             u.first = x.first + dir[i][0], u.second = x.second + dir[i][1] ;
46             if( judge(u) && !vis[u.first][u.second] ){
47                 gx[u.first][u.second] = gx[x.first][x.second] + sqrt(5) ;
48                 heap.push(make_pair(-gx[u.first][u.second]-calDis(u, t), u)) ;
49                 step[u.first][u.second] = step[x.first][x.second] + 1 ;
50             }
51         }
52     } 
53      return 0 ;
54 }
55 //
56 int main(){
57     ////////freopen("1234.txt", "r", stdin) ;
58     char a, b, c, d ;
59     while( scanf("%c%c %c%c\n", &a, &b, &c, &d) != EOF ){
60         s = make_pair(a-a+1, b-0) ;
61         t = make_pair(c-a+1, d-0) ;
62         int step = solve() ;
63         printf("To get from %c%c to %c%c takes %d knight moves.\n", a, b, c, d, step) ;
64     }
65     return 0 ;
66 }

 

例题解释A*

标签:

原文地址:http://www.cnblogs.com/be-saber/p/4780682.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!