【启发式搜索】[HDU 1372]Knight Moves
其实直接用BFS好像也可以AC但是用了A*可以更快,所以为了练习A*还是用A*老老实实写吧。估价函数就是到终点的曼哈顿距离除以3因为每走一步曼哈顿距离最多减少3,而且在所有情况下
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <iostream>
using namespace std;
struct State{
int x, y;
int g, h, f;
bool operator < (const State& s) const {
return f > s.f;
}
};
int f[9][9], fx[8][2] = {{-2, 1}, {-2, -1}, {-1, -2}, {-1, 2}, {1, -2}, {1, 2}, {2, 1}, {2, -1}};
priority_queue<State> que;
inline bool check(State st){
return st.x >= 1 && st.x <= 8 && st.y >= 1 && st.y <= 8;
}
int mabs(int u){return u>0?u:-u;}
int _h(State now, State _end){
return (mabs(now.x - _end.x) + mabs(now.y - _end.y)) / 3;
}
void PrintINFO(State st){
printf("-------%d-%d----------\n", st.x, st.y);
printf("f=%d=g=%d+h=%d\n", st.f, st.g, st.h);
printf("--------------------\n");
}
int Astar(State _start, State _end){
memset(f, 0x3f, sizeof f);
while(!que.empty()) que.pop();
State tmp = _start, tmp2;
que.push(tmp);
f[tmp.x][tmp.y] = tmp.f;
while(!que.empty()){
tmp = que.top(); que.pop();
if(tmp.x == _end.x && tmp.y == _end.y)
return tmp.g;
for(int i=0;i<8;i++){
tmp2 = tmp;
tmp2.x += fx[i][0], tmp2.y += fx[i][1];
if(check(tmp2)){
tmp2.g++;
tmp2.h = _h(tmp2, _end);
tmp2.f = tmp2.g + tmp2.h;
if(f[tmp2.x][tmp2.y] > tmp2.f){
f[tmp2.x][tmp2.y] = tmp2.f;
que.push(tmp2);
}
}
}
}
return 1000000000;
}
int main(){
char from[6], to[6];
while(scanf("%s%s", from, to) != EOF){
State star, ed;
star.x = from[0] - 'a' + 1, star.y = from[1] - '0';
ed.x = to[0] - 'a' + 1, ed.y = to[1] - '0';
star.h = _h(star, ed); star.g = 0;
star.f = star.h + star.g;
printf("To get from %s to %s takes %d knight moves.\n", from, to, Astar(star, ed));
}
return 0;
}