题意:一个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;
}