国际象棋走马步,用A*算法A了,但用时挺长的,估计还是简单BFS快多了,代码也好写……
#include <cstdio> #include <map> #include <algorithm> #include <cmath> using namespace std; typedef struct { int c_, n_; } Position; inline bool IsEqual(const Position &a, const Position &b) { return a.c_ == b.c_ && a.n_ == b.n_; } inline bool IsLegal(const Position &pos) { return pos.c_ >= 1 && pos.c_ <= 8 && pos.n_ >= 1 && pos.n_ <= 8; } typedef struct { int g_; int h_; int f_; } Node; struct PosComp { inline bool operator ()(const Position &a, const Position &b) { return a.c_ < b.c_ || (a.c_ == b.c_ && a.n_ < b.n_); } }; typedef map<Position, Node, PosComp> Map; int dir[8][2] = { 1, 2, 1, -2, 2, 1, 2, -1, -1, 2, -1, -2, -2, 1, -2, -1 }; int H(const Position &pos, const Position &dst) { return (fabs(pos.c_ - dst.c_) + fabs(pos.n_ - dst.n_)) / 3; } inline void CalF(Node *node) { node->f_ = node->g_ + node->h_; } typedef pair<Position, Node> Pair; inline bool MapItComp(const Pair &a, const Pair &b) { return a.second.f_ < b.second.f_; } int GetMinMovesCount(const Position &src, const Position &dst) { Map open, close; Node src_n = {0}; src_n.h_ = H(src, dst); CalF(&src_n); open[src] = src_n; while (!open.empty()) { Map::iterator it = min_element(open.begin(), open.end(), MapItComp); Position cur_pos = it->first; Node cur_node = it->second; if (IsEqual(cur_pos, dst)) { return cur_node.g_; } close[cur_pos] = cur_node; open.erase(it); for (int i=0; i<8; ++i) { Position next_pos = { cur_pos.c_ + dir[i][0], cur_pos.n_ + dir[i][1] }; if (!IsLegal(next_pos)) continue; Node next_node; next_node.g_ = cur_node.g_ + 1; next_node.h_ = H(next_pos, dst); CalF(&next_node); Map::iterator oit = open.find(next_pos); if (oit != open.end() && oit->second.f_ <= next_node.f_) continue; Map::iterator cit = close.find(next_pos); if (cit != close.end() && cit->second.f_ <= next_node.f_) continue; open.erase(next_pos); close.erase(next_pos); open[next_pos] = next_node; } } return -1; } inline int C(char c) { return c - 'a' + 1; } inline int N(char n) { return n - '0'; } int main() { char src[3], dst[3]; while (scanf("%s%s", src, dst) != EOF) { Position src_p = {C(src[0]), N(src[1])}; Position dst_p = {C(dst[0]), N(dst[1])}; printf("To get from %s to %s takes %d knight moves.\n", src, dst, GetMinMovesCount(src_p, dst_p)); } return 0; }