题目大意:
解题思路:运用队列先进先出原理,先把a楼的层数与按的次数零入队列,之后判断a楼向上满不满足小于等于n,如果满足且向上的楼层没有被访问则进队列,再判断a楼向下满不满足大于等于1,如果满足且向下的楼层没有被访问则进队列,之后出队列第一个,如果满足层数等于B,则跳出循环,如果不满足,再依次判断入队列,如果队列空了,但仍然没有找到等于b的楼层,则表示到不了,输出-1;
#include<bits/stdc++.h>
using namespace std;
int vis[1001];
int k[1001];
int n,a,b;
struct flor{
int level;//楼层
int times;//按的次数
};
void bfs()
{
flor now,nex;//当前楼层与下一个楼层
queue<flor>que;
now.level =a;
now.times =0;
que.push(now);//当前楼层入队列
vis[a]=0;//标记访问过的楼层
while(!que.empty())
{
now=que.front();
que.pop();//出队列
if(now.level ==b)//如果楼层等于目标楼层,跳出循环
break;
nex.level =now.level +k[now.level ];
nex.times =now.times +1;
if(nex.level <=n&&vis[nex.level ]==1)//如果向上后到达的楼层存在且没有被访问
{
que.push(nex);//入队列
vis[nex.level ]=0;//将该楼层标记为已访问
}
nex.level =now.level -k[now.level ];
nex.times =now.times +1;
if(nex.level >0&&vis[nex.level ]==1)//如果向下后到达的楼层存在且没有被访问
{
que.push(nex);//入队列
vis[nex.level ]=0;//将该楼层标记为已访问
}
}
if(now.level ==b)//如果跳出循环后的楼层等于目标楼层,则输出最少按电梯次数
cout<<now.times <<endl;
else//如果跳出循环后的楼层不等于目标楼层,说明整个队列访问完毕也到达不了目标楼层
cout<<-1<<endl;
}
int main()
{
while(cin>>n&&n)
{
cin>>a>>b;
for(int i=1;i<=n;i++)
{
cin>>k[i];
vis[i]=1;
}
bfs();
}
return 0;
}
遇到的问题:忘了将访问过的楼层标记