题意:有一个奇怪的电梯,他可以停在任何一层,并且在每个楼层有一个Ki(0 <= Ki <= N)。电梯只有两个按钮:上、下。当你在第i层,如果你按下“UP”按钮,你将上升Ki层,也就是说,你将会到达第i+Ki层,如果你按下“DOWN”按钮,你会下降 Ki层,即您将前往第i-Ki层。当然,电梯不能高于N,也不能低于1。每次先输入层数N,并输入起始点和目标点,接下来N行输入每层的值,输入0结束程序,输出最少运行的次数,若无可能,输出-1。
算法:BFS
问题:第一次学习bfs算法。(注意:vis数组别忘了清空!!!找错找了好久)
思路:利用c++的queue,每次将同一层的数据依次存入队列,并将队列头保存后删除,查找队列头元素所对应的下一层,依次存入队列;重复上述操作,便可依次将该层的数据处理完,队列中便全部是下一层的了,随后进行相同操作,逐步处理下下层的数据。又因为本题所求为最小,定义vis数组标记是否走过。
代码:ac
#include<bits/stdc++.h>
using namespace std;
int N, Start, End;
int a[202];
int vis[202];
struct pos
{
int level;/*所处层数*/
int steps;/*按键次数*/
};
void bfs();
int main()
{
while (scanf("%d", &N) == 1)
{
if (N == 0) break;
scanf("%d%d", &Start, &End);
for (int i = 1; i <= N; i++)
{
scanf("%d", &a[i]);
vis[i] = 0;/*是否搜索过该节点*/
}
bfs();
}
return 0;
}
void bfs()
{
pos cur, nex;/*curent和next*/
cur.level = Start;
cur.steps = 0;
queue<pos>qu;
qu.push(cur);/*在数列中加入该头节点*/
vis[Start] = 1;
while (!qu.empty())/*数列q非空情况下进行循环*/
{
cur = qu.front();/*先存数列头*/
qu.pop();/*再删除*/
if (cur.level == End)
{
printf("%d\n", cur.steps);/*因为是一层一层搜索的,所以找到就是最小值*/
return;
}
nex.level = cur.level + a[cur.level];/*尝试向上走*/
nex.steps = cur.steps + 1;/*状态转移*/
if (nex.level <= N)/*判断是否越上界*/
{
if (vis[nex.level] == 0)
{
vis[nex.level] = 1;
qu.push(nex);/*如果不越界,就将层数存入q数列*/
}
}
nex.level = cur.level - a[cur.level];/*尝试向下走*/
nex.steps = cur.steps + 1;
if (nex.level >= 1)/*判断是否越下界*/
{
if (vis[nex.level] == 0)
{
vis[nex.level] = 1;
qu.push(nex);/*同理*/
}
}
}
printf("-1\n");/*如果之前没有return,说明没有可能,输出-1*/
return;
}