您的位置:首页 > 其它

POJ 2243 Knight Moves A*

2015-07-11 11:04 405 查看
题意:

象棋中马从一个格子到另一个格子最少需要多少步

思路:

简单BFS,主要用此题练习了A*算法

A*算法,原理同BFS,只是通过启发式函数(代码中的f,为起点到该点的代价g和该点到终点的股价h的和)来进行BFS的剪枝。

源码:

#include <cstdio>

#include <cstring>

#include <cmath>

#include <algorithm>

#include <iostream>

#include <queue>

using namespace std;

#define ABS(a) (((a)>0)?(a):(-(a)))///abs,注意每个a都需要括号,总的还需要一个括号

int vis[10][10];

char str[10];

int dx[] = {-1,-2,-2,-1,1,2,2,1};///方向

int dy[] = {-2,-1,1,2,2,1,-1,-2};

int x1,x2,y1,y2,ans;///初始坐标和目的坐标,答案

struct D

{

int x,y,step;

int f,g,h;

D(){step = 0;}

D(int _x,int _y,int _step,int _f,int _g,int _h){x = _x,y = _y,step = _step;f = _f;g = _g;h = _h;}

bool operator < (const D &a)const{return f > a.f;}///在优先队列,符号需要相反,比如小的在前需要f>a.f

};///fgh分别表示启发式函数和,从初始点到此点代价,从此点到终点股价

priority_queue<D> que;///优先队列实现

int haminton(int x,int y)///曼哈顿距离

{

// printf("x = %d,y = %d,x2 = %d,y2 = %d\n",x,y,x2,y2);

int ans = ABS(x - x2) + ABS(y - y2);

// printf("ans = %d\n\n",ans);

return ans * 10;

}

bool valid(int x,int y)

{

if(x < 0 || x > 7)

return false;

if(y < 0 || y > 7)

return false;

return true;

}

int main()

{

while(gets(str) != NULL){

x1 = str[0] - 'a';

y1 = str[1] - '1';

x2 = str[3] - 'a';

y2 = str[4] - '1';

while(!que.empty())

que.pop();

if(x1 == x2 && y1 == y2){

ans = 0;

}

else{

memset(vis, 0, sizeof(vis));

vis[x1][y1] = 1;

D temp = D(x1,y1,0,haminton(x1,y1),0,haminton(x1,y1));

que.push(temp);

ans = -1;

while(!que.empty()){

temp = que.top();

que.pop();

int x = temp.x;

int y = temp.y;

int step = temp.step;

int g = temp.g;

int h = temp.h;

// printf("x = %d,y = %d,step = %d,f = %d,g = %d,h = %d\n",x,y,step,temp.f,g,h);

if(x == x2 && y == y2){

ans = step;

break;

}

for(int i=0; i<8; i++){

int tx = x + dx[i];

int ty = y + dy[i];

int tstep = step + 1;

if(!valid(tx,ty) || vis[tx][ty] == 1)

continue;

vis[tx][ty] = 1;

int tg = 23 + g;

int th = haminton(tx,ty);

temp = D(tx,ty,tstep,tg+th,tg,th);

que.push(temp);

}

}

}

printf("To get from %c%c to %c%c takes %d knight moves.\n",str[0],str[1],str[3],str[4],ans);

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: