例題解釋A*

題目連接:html

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

題目意思很簡單,一個8*8的棋盤,給定兩個點的座標,問國際象棋裏面的騎士從一個點走到另外一個點所須要的最小步數。走的方式就是相似於中國象棋裏面的馬,八個方位。spa

通常就會直接使用BFS搜了,8*8直接搜也不會爆,如今看下使用A*。code

A*的關鍵是怎麼選取一個合適的h(x),那就是須要保證:h( x ) <= d( x, y ) + h( y ),至於緣由,參見:http://www.cnblogs.com/be-saber/p/4780564.htmlhtm

對於一步的走法,那就是一個「日」字了。blog

這時咱們就能夠選擇 歐幾里得距離, 能夠發現, h( x ), d(x, y), h(y)就是三角形的三邊(可能三點共線)了,那麼上述條件是確定知足的了。get

代碼以下:string

 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 }
相關文章
相關標籤/搜索