习题6-4 骑士的移动(Knight Moves,UVa 439)

题目描述:

        输入标准8*8国际象棋上的两个格子(列用a ~ h表示,行用1 ~ 8表示),求马最少需要多少步从起点跳到终点。

AC代码:

#include
#include
#include
using namespace std;

struct Node {
     
	int r;
	char c;
	Node(int r=0, char c='a'):r(r),c(c) {
     }
};

const int MAX_N = 10;
char s1[10], s2[10];
char c1, c2;
int r1, r2;

int dc[] = {
     -1, -2, -2, -1, 1, 2, 2, 1};
int dr[] = {
     -2, -1, 1, 2, 2, 1, -1, -2};
int d[MAX_N][MAX_N];
int vis[MAX_N][MAX_N];

void bfs(int r, char c) {
     
	queue<Node> q;
	q.push(Node(r1, c1));
	d[r][c-'a'] = 0;
	vis[r][c-'a'] = true;
	
	while(!q.empty()) {
     
		Node u = q.front(); q.pop();
		for(int i = 0; i < 8; i++) {
     
			Node v(u.r+dr[i], u.c+dc[i]);
			if(vis[v.r][v.c-'a']) continue;
			if(v.r<1 || v.r > 8 || v.c<'a' || v.c>'h') continue;
			vis[v.r][v.c-'a'] = true;
			d[v.r][v.c-'a'] = d[u.r][u.c-'a'] + 1;
			q.push(v);
		}
	}
}

int main() {
     
	#ifdef LOCAL
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
	#endif
	while(scanf("%s%s", s1, s2) == 2) {
     
		r1=s1[1]-'0'; c1=s1[0];
		r2=s2[1]-'0'; c2=s2[0];
		memset(d, -1, sizeof(d));
		memset(vis, 0, sizeof(vis));
		bfs(r1, c1);
		printf("To get from %c%d to %c%d takes %d knight moves.\n", c1, r1, c2, r2, d[r2][c2-'a']);
	}
	return 0;
}

你可能感兴趣的:(算法竞赛,bfs,算法)