题目描述
呵呵,有一天我做了一个梦,梦见了一种很奇怪的电梯。大楼的每一层楼都可以停电梯,而且第 �i 层楼(1≤�≤�1≤i≤N)上有一个数字 ��Ki(0≤��≤�0≤Ki≤N)。电梯只有四个按钮:开,关,上,下。上下的层数等于当前楼层上的那个数字。当然,如果不能满足要求,相应的按钮就会失灵。例如: 3,3,1,2,53,3,1,2,5 代表了 ��Ki(�1=3K1=3,�2=3K2=3,……),从 11 楼开始。在 11 楼,按“上”可以到 44 楼,按“下”是不起作用的,因为没有 −2−2 楼。那么,从 �A 楼到 �B 楼至少要按几次按钮呢?
输入格式
共二行。
第一行为三个用空格隔开的正整数,表示 �,�,�N,A,B(1≤�≤2001≤N≤200,1≤�,�≤�1≤A,B≤N)。
第二行为 �N 个用空格隔开的非负整数,表示 ��Ki。
输出格式
一行,即最少按键次数,若无法到达,则输出
-1
。输入输出样例
输入 #1复制
5 1 5 3 3 1 2 5输出 #1复制
3说明/提示
对于 100%100% 的数据,1≤�≤2001≤N≤200,1≤�,�≤�1≤A,B≤N,0≤��≤�0≤Ki≤N。
- 该题我采用的算法是bfs。
- 首先,理解一下题意:输入的n个数,代表在第i层只按电梯的数字a[i],但是a[i]不仅是可以上a[i]层也可以下a[i]层,但是要考虑楼层数,如果上楼超过了楼层数,就选择下楼,如果下楼低于一楼就选择上楼。
- bfs算法,设置一个结构体数组代表队列,他包含两个元素一个是当前楼层数,一个是身处该层按了多少下电梯按键,先将当前所在的楼层入队, 然后进入循环每一次都判断队首元素的当前楼层数是否已经到达了目的地,如果到了就退出循环,否则继续向上向下进行搜索,直到到达目的地或者队列为空。
- 代码:
#include"stdio.h" struct node { int x; int step; }; int s[205],vis[205]; main() { struct node e1,e2,que[205]; int i,a,b,n; int head=1,tail=1; scanf("%d %d %d",&n,&a,&b); for(i=1;i<=n;i++) scanf("%d",&s[i]); e1.x=a; e1.step=0; que[tail]=e1; vis[a]=1; tail++; while(head<tail) { e2=que[head]; head++; if(e2.x==b) break; i=e2.x+s[e2.x]; if(i<=n&&vis[i]==0) { e1.x=i; e1.step=e2.step+1; que[tail]=e1; tail++; vis[i]=1; } i=e2.x-s[e2.x]; if(i>=1&&vis[i]==0) { e1.x=i; e1.step=e2.step+1; que[tail]=e1; tail++; vis[i]=1; } } if(e2.x==b) printf("%d",e2.step); else printf("%d",-1); }