奇怪的电梯

题目链接 https://www.luogu.com.cn/problem/P1135

奉上bfs和dfs两种方法。


 

bfs:在本题中,相邻状态为当前所在楼层通过按向上或向下按钮所能到达的楼层,每个状态要记录的信息包括楼层编号和按按钮的次数。

先判断是否到达终点,是则返回x.step(到达此楼层一共需要按钮的次数),再判断下一个到达的楼层是否越界或是否已经被标记过。


放AC代码

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,a,b,ans=0;
 4 int k[210];
 5 int vis[210];//标记数组
 6 struct node
 7 {
 8     int id;//表示楼层号
 9     int step;//表示按钮次数
10 }x;
11 int bfs(int a)
12 {
13     vis[a]=1;
14     queue<node>q;
15     q.push((node){a,0});//起始点入队 
16     while(!q.empty())
17     {
18         x=q.front();
19         q.pop();
20         if(x.id==b) return x.step;
21         if(x.id+k[x.id]<=n&&!vis[x.id+k[x.id]])
22         {
23             q.push((node){x.id+k[x.id],x.step+1});
24             vis[x.id+k[x.id]]=1;
25         }
26         if(x.id-k[x.id]>=1&&!vis[x.id-k[x.id]])
27         {
28             q.push((node){x.id-k[x.id],x.step+1});
29             vis[x.id-k[x.id]]=1;
30         }
31     }
32     return -1;
33 }
34 int main()
35 {
36     ios::sync_with_stdio(false);
37     cin>>n>>a>>b;
38     for(int i=1;i<=n;i++)
39         cin>>k[i];
40     cout<<bfs(a);
41     return 0;
42 }

 

dfs:利用剪枝的思想,若到达终点后,将sum赋给ans,继续搜索,直到sum继续增大超过最优结果ans,则return,这样有最优结果ans依然没有被改变,所以判断是否到达终点(第8行)和剪枝(第9行)语句可以互换位置,结果相同。


放AC代码

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,a,b,ans=0xffffff;//即INT_MAX
 4 int vis[210];
 5 int k[210];
 6 void dfs(int now,int sum)
 7 {
 8     if(now==b) ans=min(ans,sum);
 9     if(sum>ans) return;//剪枝
10     vis[now]=1;//标记已走
11     //不越界就搜
12     if(now+k[now]<=n&&!vis[now+k[now]]) dfs(now+k[now],sum+1);
13     if(now-k[now]>=1&&!vis[now-k[now]]) dfs(now-k[now],sum+1);
14     vis[now]=0;//回溯
15 }
16 int main()
17 {
18     cin>>n>>a>>b;
19     for(int i=1;i<=n;i++)
20     {
21         cin>>k[i];
22     }
23     vis[a]=1;
24     dfs(a,0);
25     if(ans!=0xffffff) cout<<ans;
26     else cout<<-1;
27     return 0;
28 }

 

posted @ 2022-03-30 08:52  爱吃虾滑  阅读(72)  评论(0编辑  收藏  举报