这题利用 dfs 解决,编程实现比较简单。
具体来说,每层楼有两种可能,上楼或下楼,因此可以形成一个以 a 楼为根的二叉树,因此只需一个 for 循环遍历某个父节点的两个子节点,之后递归就行。
易错点:这题的判断条件不再是 N-皇后那样判断是否访问过某层楼,而是判断当前走到某层楼的步数,是否小于原先走到该层楼所需步数(因为有多种方式可以走到某层楼,我们要找出其中所需步数最小的那种),如果小于就替换掉原先走到该层所需的步数。
#include<iostream>
#include<string.h>
using namespace std;
const int N = 210;
int n, a, b, k[N], ans[N];
void dfs(int u)
{
for(int i=-1; i<=1; i+=2)
{
int next = u + i*k[u]; // 下一步去到的楼层
if(ans[next] > ans[u] + 1 && next >= 1 && next <= n)
{
ans[next] = ans[u] + 1;
dfs(next);
}
}
}
int main()
{
scanf("%d%d%d", &n, &a, &b);
for(int i=1;i<=n;++i) scanf("%d", &k[i]);
if(a != b)
{
memset(ans, 0x3f, sizeof(ans));
ans[a] = 0;
dfs(a);
if(ans[b] != 0x3f3f3f3f)
printf("%d", ans[b]);
else
printf("%d", -1);
}
else
printf("%d", 0);
return 0;
}