详细的A*算法参考文章:http://www.cppblog.com/mythit/archive/2009/04/19/80492.aspx
http://acm.pku.edu.cn/JudgeOnline/problem?id=2243
在国际象棋的棋盘上,一匹马共有8个可能的跳跃方向,求从起点到目标点之间的最少跳跃次数。
#include <iostream>
#include<string>
#include<cmath>
#include<queue>
#include<algorithm>
#include<functional>
#include<numeric>
using namespace std;
struct Node{
int x,y,step;
int f,h,g;
bool operator<(const Node&a) const{
return f>a.f;
}
};
Node sNode,eNode;
const int N=8;
int dirs[N][2]={{2,1},{1,2},{-1,2},{-2,-1},{-2,1},{-1,-2},{1,-2},{2,-1}};
bool visited[N][N];
inline bool check(const Node& node){
return !(node.x<0||node.y<0||node.x>=N||node.y>=N);
}
int h(const Node& node){//采用曼式距离进行估计
return 10*abs(node.x-eNode.x)+abs(node.y+eNode.y);
}
void astar(){
priority_queue<Node> que;
que.push(sNode);
while(!que.empty()){
Node t=que.top();
que.pop();
visited[t.x][t.y]=true;
if(t.x==eNode.x&&t.y==eNode.y){
cout<<t.step<<endl;
return;
}
Node s;
for(int i=0;i<N;++i){
s.x=t.x+dirs[i][0];
s.y=t.y+dirs[i][1];
if(!check(s)||visited[s.x][s.y]) continue;
s.g=t.g+23;
s.h=h(s);
s.f=s.g+s.h;
s.step=t.step+1;
que.push(s);
}
}
}
int main()
{
char line[]="a1h8";//从a1到h8
sNode.x=line[0]-'a',sNode.y=line[1]-'1';
eNode.x=line[2]-'a',eNode.y=line[3]-'1';
memset(visited,false,sizeof(visited));
sNode.g=0;sNode.h=h(sNode),sNode.f=sNode.g+sNode.h;
sNode.step=0;
astar();
system("pause");
return 0;
}