题意:
问国际象棋棋盘上knight从一个位置走到另一个位置有多少种走法。knight可八方向移动。
思路:
经典的BFS问题。使用队列即可解决。
#include <stdio.h>
#include <string.h>
#include <queue>
const int N = 8;
const int M = 8;
const int MV[M][2]= {2, 1, 1, 2, -2, 1, -1, 2, 2, -1, 1, -2, -1, -2, -2, -1};
typedef std::pair<int, int> Cell;
int steps[N + 1][N + 1];
int bfs(const Cell& start, const Cell& end) {
if (start == end) {
return 0;
}
std::queue<Cell> que;
que.push(start);
memset(steps, -1, sizeof(steps));
steps[start.first][start.second] = 0;
while (!que.empty()) {
Cell cell = que.front();
que.pop();
for (int i = 0; i < M; ++i) {
Cell next(cell.first + MV[i][0], cell.second + MV[i][1]);
if (next.first < 0 || next.second < 0 || next.first >= N || next.second >= N) {
continue;
}
if (steps[next.first][next.second] > 0) {
continue;
}
steps[next.first][next.second] = steps[cell.first][cell.second] + 1;
if (next == end) {
return steps[next.first][next.second];
}
que.push(next);
}
}
return -1;
}
int main() {
char start_str[3], end_str[3];
while(scanf("%s%s", start_str, end_str) != EOF) {
Cell start(start_str[0] - 'a', start_str[1] - '1');
Cell end(end_str[0] - 'a', end_str[1] - '1');
int ans = bfs(start, end);
printf("To get from %s to %s takes %d knight moves.\n", start_str, end_str, ans);
}
return 0;
}