Luogu P1135 奇怪的电梯 再谈广搜

P1135

广度优先搜索易解的问题有如下的特点:

  1. 最短为最优
  2. 每个节点处的规则都唯一确定(不管各个节点的规则是否都相同),保证了单节点只扩展一次。

这个题就能很典型地体现第二点。

分析

这个题目走到每一个节点的时候,上下移动的规则都是相同的,所以扩展一次就不用再次扩展了,采用广度搜索的标准模板即可解。

另外

  1. 如果每个节点处的规则由深度而确定,那么则应使用深度优先搜索。因为广搜时要记录每一层不同的操作数量和操作规则。实在困难。
  2. 如果中途还能停的话,应该使用广搜(同时不pop,看起来也就不像是典型的广搜了),但是其复杂度会动态增大。

代码

一个典型的广搜问题,不要被这个不同节点的不同规则而搞乱掉了,毕竟每一节点(在题目中具体为楼层,不是搜索的层)都是一个确定的规则,随意扩展完后去除掉即可。复杂度是线性的。

#include <bits/stdc++.h>
using namespace std;
struct s
{
     int f, n;
     s(int _f, int _n) : f(_f), n(_n) { }
};
int k[205], vis[205];
int main()
{
     queue<s> q;
     int N, a, b;
     cin >> N >> a >> b;
     for (int i = 1; i <= N; i++)
          cin >> k[i];
     q.push(s(a, 0)); vis[a] = 1;
     int tf, tn;
     while (!q.empty())
     {
          tf = q.front().f, tn = q.front().n; q.pop();
          if (tf == b) break;
          int t1 = tf + k[tf], t2 = tf - k[tf];
          if (t1 <= N && !vis[t1])
               q.push(s(t1, tn+1)), vis[t1] = 1;
          if (t2 >= 1 && !vis[t2])
               q.push(s(t2, tn+1)), vis[t2] = 1;
     }
     if (tf == b) cout << tn;
     else cout << "-1";
}

猜你喜欢

转载自blog.csdn.net/weixin_45502929/article/details/106600174