P1588 [USACO07OPEN] Catch That Cow S 最短路广搜
题目分析
这是一道经典的 一维BFS(广度优先搜索) 题目,要求计算农夫(FJ)从起点 x 到终点 y 的最少步数,每次移动可以选择:
-
前进一步(
x + 1) -
后退一步(
x - 1) -
直接跳跃到
2 * x的位置
由于每次移动的步数相同(每一步的代价都是 1),BFS 能够保证首次到达终点时的步数一定是最小的。
代码解析(带详细注释)
#include<bits/stdc++.h> using namespace std; const int N = 1e5 + 10; // 定义坐标的最大范围 struct node { int x, step; // x: 当前坐标,step: 走到当前坐标的步数 }; int vis[N]; // 标记数组,记录某个坐标是否被访问过 int n, k; // n: 起点,k: 终点(牛的位置) void bfs(int s) { queue<node> q; // 定义队列,用于BFS q.push({s, 0}); // 起点入队,初始步数为0 vis[s] = 1; // 标记起点已访问 while (q.size()) { // 队列不为空时循环 int x = q.front().x, st = q.front().step; // 取出队首元素 q.pop(); // 弹出队首 // 遍历三种可能的移动方式 for (int i = 0; i < 3; i++) { int tx; // 临时变量,存储移动后的新坐标 if (i == 0) tx = x - 1; // 后退一步 if (i == 1) tx = x + 1; // 前进一步 if (i == 2) tx = x * 2; // 跳跃到 2 * x // 检查新坐标是否越界或已访问 if (tx < 0 || tx >= N) continue; // 越界则跳过 if (vis[tx] == 0) { // 如果未访问过 q.push({tx, st + 1}); // 入队,步数+1 vis[tx] = 1; // 标记已访问 } // 如果到达终点,直接输出步数并返回 if (tx == k) { cout << st + 1 << endl; return; } } } } void solve() { cin >> n >> k; // 输入起点和终点 memset(vis, 0, sizeof(vis)); // 初始化访问标记数组 bfs(n); // 从起点开始BFS } int main() { int T; cin >> T; // 输入数据组数 while

浙公网安备 33010602011771号