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;
}