P1135 奇怪的电梯 广搜
题目分析
这道题是一道典型的 BFS(广度优先搜索) 题目,要求计算从楼层 A 到楼层 B 的最少按键次数。电梯的移动规则是:
-
每次可以 向上或向下 移动
K_i层(K_i是当前楼层i的数字)。 -
如果移动后的楼层超出
1~N的范围,则该方向不可行。
由于每次移动的代价相同(每次按键算一步),BFS 可以保证首次到达目标楼层时的按键次数最少。
代码解析(带详细注释)
#include<bits/stdc++.h> using namespace std; const int N = 1e5 + 10; // 定义足够大的数组范围(题目中 N ≤ 200) struct node { int x, step; // x: 当前楼层,step: 走到当前楼层的按键次数 }; int vis[N]; // 标记数组,记录某个楼层是否被访问过 int n, a, b; // n: 总楼层数,a: 起点,b: 终点 int k[N]; // 存储每层楼的 K_i 值 int nex[2] = {-1, 1}; // 移动方向:-1(向下),1(向上) void bfs(int a) { queue<node> q; // 定义队列,用于BFS vis[a] = 1; // 标记起点已访问 q.push({a, 0}); // 起点入队,初始按键次数为0 while (q.size()) { // 队列不为空时循环 int x = q.front().x, d = q.front().step; // 取出队首元素 q.pop(); // 弹出队首 // 遍历两种可能的移动方向(上、下) for (int i = 0; i < 2; i++) { int tx = x + nex[i] * k[x]; // 计算移动后的新楼层 if (tx < 1 || tx > n) continue; // 越界则跳过 if (vis[tx]) continue; // 已访问则跳过 vis[tx] = 1; // 标记新楼层已访问 q.push({tx, d + 1}); // 入队,按键次数+1 if (tx == b) { // 如果到达终点 cout << d + 1 << endl; // 输出按键次数 return; // 直接返回 } } } cout << -1 << endl; // 队列空仍未到达终点,输出-1 } int main() { cin >> n >> a >> b; // 输入总楼层数、起点、终点 for (int i = 1; i <= n; i++) cin >> k[i]; // 输入每层楼的 K_i if (a == b) { // 特判:起点等于终点时直接输出0 cout << 0 << endl; return 0; } bfs(a); return 0; }

浙公网安备 33010602011771号