POJ 2243 Knight Moves 广搜可直接水,这里用A*搜索


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




猜你喜欢

转载自blog.csdn.net/triple_wdf/article/details/80638496