思路分析
电梯的上下可以看作是两个方向的运动,题目中要求最短的路径,那么优先考虑BFS(广度优先搜索)。结合连表结构就可以解决问题。
https://www.luogu.com.cn/problem/P1135https://www.luogu.com.cn/problem/P1135
代码解析
定义部分
首先,我们需要一个数组来记录每个楼层可以上(下)的层数;
一个布尔类型的数组来记录楼层是否被访问;
储存现在楼层的fn (floor now);
一个结构体来记录实时的楼层变化和按按钮的次数;
int a[205];
bool ch[205];
int fn;
struct flor{
int i;//记录楼层
int s;//记录步数
};
flor flr[205];
准备部分
准备部分主要初始化队列,并准备好接下所要用到数组等
memset(ch,0,sizeof(ch));//别忘记归零
int n,A,B;
cin>>n>>A>>B;
if(A==B) //起始楼层与终点楼层相同时不需要按按钮
{
cout<<0;
return 0;//输出后立即终止程序
}
for(int i=1;i<=n;i++)
cin>>a[i];
int head=1,
tail=2;
flr[head].i=A;
flr[head].s=0;
//标记头尾及元素值
int flag=0;//用来记录是否到达终点楼层
int updown[2];//储存上下的层数
主体部分
从两个方向出发,广度搜索楼层,第一个到达的就是最短路径
队列不为空时进入循环,当某时刻队列为空时,表示穷途末路,输出-1并结束程序
下面的代码中注释了两条输出函数,代码出错时可以取消注释,运行后找出问题(调试)
while(tail>head)//队列不为空时进入循环
{
updown[0]=a[flr[head].i];
updown[1]=-a[flr[head].i];
for(int i=0;i<2;i++)
{
fn=flr[head].i+updown[i];//cout<<"*"<<fn<<endl;代码出错时可以取消注释,来调试
if(fn<1||fn>n||ch[fn]==1) continue;
//cout<<fn<<endl;不带*的表示已经满足if的条件
flr[tail].i=fn;//将该楼层放入队列
flr[tail].s=flr[head].s+1;//步数在父亲的基础上加一
ch[fn]=1;//标记楼层已被访问
tail++;//准备添加队列成员
if(fn==B)//判断是否到达
{
flag=1;
break;
}
}
if(flag==1) break;
head++;
if(tail<=head)//队列为空时表示现在已经无路可走
{
cout<<-1;
return 0;
}
}
cout<<flr[tail-1].s;
return 0;
代码展示
理清思路,多上手尝试,连贯就不是问题
#include<bits/stdc++.h>
using namespace std;
int a[205];
bool ch[205];
int fn;
struct flor{
int i;//记录楼层
int s;//记录步数
};
flor flr[205];
int main()
{
memset(ch,0,sizeof(ch));//别忘记归零
int n,A,B;
cin>>n>>A>>B;
if(A==B) //起始楼层与终点楼层相同时不需要按按钮
{
cout<<0;
return 0;//输出后立即终止程序
}
for(int i=1;i<=n;i++)
cin>>a[i];
int head=1,
tail=2;
flr[head].i=A;
flr[head].s=0;
//标记头尾及元素值
int flag=0;//用来记录是否到达终点楼层
int updown[2];//储存上下的层数
while(tail>head)//队列不为空时进入循环
{
updown[0]=a[flr[head].i];
updown[1]=-a[flr[head].i];
for(int i=0;i<2;i++)
{
fn=flr[head].i+updown[i];//cout<<"*"<<fn<<endl;代码出错时可以取消注释,来调试
if(fn<1||fn>n||ch[fn]==1) continue;
//cout<<fn<<endl;不带*的表示已经满足if的条件
flr[tail].i=fn;//将该楼层放入队列
flr[tail].s=flr[head].s+1;//步数在父亲的基础上加一
ch[fn]=1;//标记楼层已被访问
tail++;//准备添加队列成员
if(fn==B)//判断是否到达
{
flag=1;
break;
}
}
if(flag==1) break;
head++;
if(tail<=head)//队列为空时表示现在已经无路可走
{
cout<<-1;
return 0;
}
}
cout<<flr[tail-1].s;
return 0;
}