题目描述
输入格式
输出格式
题意翻译
输入8*8的国际象棋棋盘上的2个格子(列:a~h,行:1~8),求马至少多少步从起点(键盘输入的第一个位置)跳到终点(键盘输入的第二个位置)。
感谢 @陶文祥 提供的翻译。
输入输出样例
输入
e2 e4 a1 b2 b2 c3 a1 h8 a1 h7 h8 a1 b1 c3 f6 f6
输出
To get from e2 to e4 takes 2 knight moves. To get from a1 to b2 takes 4 knight moves. To get from b2 to c3 takes 2 knight moves. To get from a1 to h8 takes 6 knight moves. To get from a1 to h7 takes 5 knight moves. To get from h8 to a1 takes 6 knight moves. To get from b1 to c3 takes 1 knight moves. To get from f6 to f6 takes 0 knight moves.
AC代码如下:
#include <bits/stdc++.h>
using namespace std;
struct pos {
int x;//行
int y;//列
int steps;
};
int dir[8][2] = {{-1, -2}, {-1, 2}, {1, 2}, {1, -2}, {-2, -1}, {-2, 1}, {2, 1}, {2, -1}}; //方向数组 移动的8个方位
int Map[10][10], ex, ey;
char a[5], b[5];
int check(int x, int y) {//检查是否越界+剪枝
if (x < 0 || x > 7 || y < 0 || y > 7 || Map[x][y])
return 0;
return 1;//合法
}
int bfs() {
queue<pos> q;
pos cur, nex;
//起始坐标
cur.x = a[0] - 'a';//转化成数字坐标形式
cur.y = a[1] - '1';
cur.steps = 0;
memset(Map, 0, sizeof(Map));
Map[cur.x][cur.y] = 1;
//目标坐标
ex = b[0] - 'a';
ey = b[1] - '1';
q.push(cur);
while (!q.empty()) {
cur = q.front();
q.pop();
if (cur.x == ex && cur.y == ey)
return cur.steps;
for (int i = 0; i < 8; i++) {
nex.x = cur.x + dir[i][0];
nex.y = cur.y + dir[i][1];
if (nex.x == ex && nex.y == ey)
return cur.steps + 1;
if (check(nex.x, nex.y)) { //移动合法
nex.steps = cur.steps + 1;
Map[nex.x][nex.y] = 1;
q.push(nex);
}
}
}
return -1;//无法走到终点
}
int main() {
while (~scanf("%s%s", a, b)) {//~表示输入取反,控制while循环
printf("To get from %s to %s takes %d knight moves.\n", a, b, bfs());
}
return 0;
}