1 条题解
-
0
解题思路:
-
建模棋盘:
- 棋盘是8x8的,列用字母
a-h
表示,行用数字1-8
表示。 - 将棋盘坐标转换为二维数组索引(例如
a1
→(0, 0)
,h8
→(7, 7)
)。
- 棋盘是8x8的,列用字母
-
BFS(广度优先搜索):
- BFS适用于无权图的最短路径问题,因为它的遍历方式是按层进行的,最早找到目标时步数一定最少。
- 从起始点出发,逐层扩展所有可能的移动,直到找到目标点。
-
骑士的移动方式:
- 骑士有8种可能的移动方向:
(dx, dy) ∈ [(2,1), (2,-1), (-2,1), (-2,-1), (1,2), (1,-2), (-1,2), (-1,-2)]
- 骑士有8种可能的移动方向:
-
BFS实现步骤:
- 初始化:起点入队,步数=0,标记已访问。
- 逐层扩展:
- 取出队首节点,检查是否为目标点。
- 遍历8个方向,计算新位置
(nx, ny)
。 - 如果新位置合法(在棋盘内且未访问过),则入队,并记录步数+1。
- 终止条件:找到目标点或队列为空(理论上棋盘是连通的,不会出现无法到达的情况)。
-
边界情况:
- 起点和终点相同 → 直接返回0。
- 输入坐标转换时注意字母和数字的映射(
a
→0,1
→0)。
c++实现
#include <iostream> #include <queue> #include <vector> #include <string> #include <utility> #include <climits> using namespace std; struct Position { int x, y; Position(int x = 0, int y = 0) : x(x), y(y) {} }; int knightMoves(const Position& start, const Position& end) { if (start.x == end.x && start.y == end.y) { return 0; } const int dx[] = {2, 1, -1, -2, -2, -1, 1, 2}; const int dy[] = {1, 2, 2, 1, -1, -2, -2, -1}; queue<Position> q; vector<vector<int> > steps(8, vector<int>(8, -1)); q.push(start); steps[start.x][start.y] = 0; while (!q.empty()) { Position current = q.front(); q.pop(); for (int i = 0; i < 8; ++i) { int nx = current.x + dx[i]; int ny = current.y + dy[i]; if (nx >= 0 && nx < 8 && ny >= 0 && ny < 8 && steps[nx][ny] == -1) { steps[nx][ny] = steps[current.x][current.y] + 1; if (nx == end.x && ny == end.y) { return steps[nx][ny]; } q.push(Position(nx, ny)); } } } return -1; } Position parsePosition(const string& pos) { int x = pos[0] - 'a'; int y = pos[1] - '1'; return Position(x, y); } int main() { string a, b; while (cin >> a >> b) { Position start = parsePosition(a); Position end = parsePosition(b); int steps = knightMoves(start, end); cout << "To get from " << a << " to " << b << " takes " << steps << " knight moves." << endl; } return 0; }
-
- 1
信息
- ID
- 1244
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者