P1135 奇怪的电梯

简单的搜索题,初学者板子题

思路

从初始楼层进行搜索,只要没有越界,就向上下两个方向进行搜索,每一次到达目标楼层就更新一次最优答案,搜完为之。

技巧:若搜索过程中的操作步数已经大于最优解,仍然没有到达目标楼层,直接进行回溯。

代码实现

深度优先搜索,DFS

#include <algorithm>
#include <cstdio>
#define maxn 205
#define INF 0x7ffffff
using namespace std;

int n, a, b, ans = INF;
int k[maxn];
bool vis[maxn];

void dfs(int p, int sum) {//p表示当前楼层,sum表示操作的次数
  if (p == b) {//若到达目标楼层,更新最优解
  	ans = min(ans, sum);
  }
  if (sum > ans) return ;//大于当前最优解,直接回溯
  vis[p] = 1;
  if (p + k[p] <= n && !vis[p + k[p]]) dfs(p + k[p], sum+1);//不越界就继续搜
  if (p - k[p] >= 1 && !vis[p - k[p]]) dfs(p - k[p], sum+1);
  vis[p] = 0;
}

int main() {
  scanf("%d%d%d", &n, &a, &b);
  for (int i = 1; i <= n; ++i) scanf("%d", &k[i]);
  vis[a] = 1;//当前楼层一定被遍历
  dfs(a, 0);
  if (ans != 0x7ffffff) printf("%d\n", ans);//有答案,进行输出
  else printf("-1\n");//无答案,输出-1
  return 0;//结束
}

广度优先搜索,BFS

#include <queue>
#include <cstdio>

using namespace std;

int n, a, b, to[205];
bool vis[205];
struct node{
  int fl, step;
}x;//fl表示楼层号,step表示按钮次数
queue<node> q;

int main() {
  scanf("%d%d%d", &n, &a, &b);
  for (int i = 1; i <= n; ++i) 
	scanf("%d",&to[i]);
  q.push((node){a, 0});
  while (q.size())
  {
	x = q.front();
	q.pop();
	if (x.fl == b) break;
	if (x.fl + to[x.fl] <= n && !vis[x.fl + to[x.fl]]) {
	  q.push((node){x.fl + to[x.fl], x.step + 1});
	  vis[x.fl + to[x.fl]] = 1;
	}
	if (x.fl - to[x.fl] >= 1 && !vis[x.fl - to[x.fl]]) {
	  q.push((node){x.fl - to[x.fl], x.step + 1});
	  vis[x.fl - to[x.fl]] = 1;
	}
  }
  if(x.fl == b) printf("%d", x.step);
  else printf("-1");
  return 0;
}

posted @ 2020-07-07 14:03  柠月与梦  阅读(164)  评论(0编辑  收藏  举报