原题链接:
落谷 https://www.luogu.com.cn/problem/P1135
信息奥赛一本通 http://ybt.ssoier.cn:8088/problem_show.php?pid=1360
题目:
大楼的每一层楼都可以停电梯,而且第i层楼(1≤i≤N)上有一个数字Ki(0≤=Ki≤=N)。电梯只有四个按钮:开,关,上,下。上下的层数等于当前楼层上的那个数字。当然,如果不能满足要求,相应的按钮就会失灵。例如:3 3 1 2 5
代表了Ki(K1=3,K2=3,……),从一楼开始。在一楼,按“上”可以到4楼,按“下”是不起作用的,因为没有−2楼。那么,从A楼到B楼至少要按几次按钮呢?
共有二行,第一行为三个用空格隔开的正整数,表示N,A,B(1≤N≤200,1≤A,B≤N),第二行为N个用空格隔开的正整数,表示Ki。
一行,即最少按键次数,若无法到达,则输出−1。
5 1 5 3 3 1 2 5
3
这是一道搜索题,这里可以运用广搜。
首先写一个队列a,h代表当前在几楼,C代表走了几步。
初始化就是先将初始楼层加入队列,
搜索过程就是讲队首元素取出,然后将在对首元素所在楼层按键后所能到达的楼层加入队尾,并且次数加一,如果到达指定楼层就输出次数,最后head++继续搜下一个,
循环条件就是队列非空,即head<=tail,
如果循环结束还没到达指定楼层就代表无法到达,输出-1。
代码:
c:
#include<stdio.h> struct k{ int h,c;//h代表当前在几楼,C代表走了几步 }a[201];//广搜队列 int b[201];//存储数据 int ye[201];//记录楼层是否到达 int m,n,r,s; int head,tail; int main(){ scanf("%d%d%d",&n,&r,&s); for(int i=1;i<=n;i++)scanf("%d",b+i); if(r==s){printf("0");return 0;}//如果初始楼层和目标楼层相同则不用走 a[0].h=r;a[0].c=0;// 初始楼层加入队列 tail=head=0; while(head<=tail){//广搜 ,循环条件就是队列非空 if(a[head].h+b[a[head].h]<=n&&ye[a[head].h+b[a[head].h]]==0){//向上走 ye[a[head].h+b[a[head].h]]=1;//记录该楼层已经走过 a[++tail].h=a[head].h+b[a[head].h];//楼层按键后所能到达的楼层加入队尾 a[tail].c=a[head].c+1;//并且次数加一 if(a[tail].h==s){printf("%d",a[tail].c);return 0;}//如果到达指定楼层就输出次数 } if(a[head].h-b[a[head].h]>=1&&ye[a[head].h-b[a[head].h]]==0){//向下走 ye[a[head].h-b[a[head].h]]=1;//记录该楼层已经走过 a[++tail].h=a[head].h-b[a[head].h];//楼层按键后所能到达的楼层加入队尾 a[tail].c=a[head].c+1;//并且次数加一 if(a[tail].h==s){printf("%d",a[tail].c);return 0;}//如果到达指定楼层就输出次数 } head++;//对首加1 } printf("-1");return 0;//如果循环结束还没到达指定楼层就代表无法到达,输出-1 }
pascal:
type k=record h:longint; c:longint;//h代表当前在几楼,C代表走了几步 end; var a:array[0..200]of k;//广搜队列 b:array[1..200]of longint;//存储数据 ye:array[1..200]of boolean;//记录楼层是否到达 m:longint; n:longint; r:longint; s:longint; head:longint; tail:longint; i:longint; begin read(n,r,s); for i:=1 to n do read(b[i]); if r=s then begin writeln(0);exit();//如果初始楼层和目标楼层相同则不用走 end; a[0].h:=r;a[0].c:=0; // 初始楼层加入队列 head:=0;tail:=head; while head<=tail do begin //广搜 ,循环条件就是队列非空 if (a[head].h+b[a[head].h]<=n)and(ye[a[head].h+b[a[head].h]]=false)then begin //向上走 ye[a[head].h+b[a[head].h]]:=true;//记录该楼层已经走过 tail:=tail+1; a[tail].h:=a[head].h+b[a[head].h]; //楼层按键后所能到达的楼层加入队尾 a[tail].c:=a[head].c+1;//并且次数加一 if a[tail].h=s then begin writeln(a[tail].c);exit();//如果到达指定楼层就输出次数 end; end; if (a[head].h-b[a[head].h]>=1)and(ye[a[head].h-b[a[head].h]]=false)then begin //向下走 ye[a[head].h-b[a[head].h]]:=true;//记录该楼层已经走过 tail:=tail+1; a[tail].h:=a[head].h-b[a[head].h]; //楼层按键后所能到达的楼层加入队尾 a[tail].c:=a[head].c+1;//并且次数加一 if a[tail].h=s then begin writeln(a[tail].c);exit();//如果到达指定楼层就输出次数 end; end; head:=head+1;//对首加1 end; writeln(-1);//如果循环结束还没到达指定楼层就代表无法到达,输出-1 end.
我可能写的不好,如果有问题,请指出,谢谢。
落谷P1135信息奥赛一本通1360 奇怪的电梯(lift)
原文:https://www.cnblogs.com/sy666/p/12403973.html