题意:一个8 * 8的棋盘从起点跳到终点要走多少步,骑士走“日”。“a5”其中5是行号,a是列号
想法:正常广搜就能过,用A*,G = 走的步数 * 3(也可以直接就等于步数),H = 两点之间的水平距离和垂直距离之和。采用优先队列,将G + H值小的放队列前面。
#include<iostream> #include<cstring> #include<queue> using namespace std; struct node{ int x, y; int G, H; bool operator < (const node &a) const{ return G + H > a.G + a.H; } }st, ed; int dir[8][2] = {-2, 1, -2, -1, 2, 1, 2, -1, -1, 2, -1, -2, 1, 2, 1, -2}; int Abs(int x) { if(x > 0) return x; return -x; } int get_H(int x, int y) { return Abs(x - ed.x) + Abs(y - ed.y); } int A_star() { if(st.x == ed.x && st.y == ed.y) return 0; bool visit[10][10]; priority_queue<node>q; while(!q.empty()) q.pop(); memset(visit, false, sizeof(visit)); st.G = 0; st.H = get_H(st.x, st.y); visit[st.x][st.y] = true; q.push(st); while(!q.empty()){ node cur_node = q.top(); q.pop(); for(int k = 0; k <= 7; ++k){ node nxt_node; nxt_node.x = cur_node.x + dir[k][0]; nxt_node.y = cur_node.y + dir[k][1]; if(!visit[nxt_node.x][nxt_node.y] && nxt_node.x >= 1 && nxt_node.x <= 8 && nxt_node.y >= 1 && nxt_node.y <= 8){ visit[nxt_node.x][nxt_node.y] = true; nxt_node.G = cur_node.G + 3; if(nxt_node.x == ed.x && nxt_node.y == ed.y) return nxt_node.G / 3; nxt_node.H = get_H(nxt_node.x, nxt_node.y); q.push(nxt_node); } } } return -1; } int main() { char a[5], b[5]; while(cin>>a>>b){ st.x = a[1] - '0'; st.y = a[0] - 'a' + 1; ed.x = b[1] - '0'; ed.y = b[0] - 'a' + 1; cout<<"To get from "<<a<<" to "<<b<<" takes "<<A_star()<<" knight moves."<<endl; } return 0; }