P1135-奇怪的电梯

137 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第9天,点击查看活动详情

奇怪的电梯

题目描述

呵呵,有一天我做了一个梦,梦见了一种很奇怪的电梯。大楼的每一层楼都可以停电梯,而且第 ii 层楼(1iN1 \le i \le N)上有一个数字 KiK_i0KiN0 \le K_i \le N)。电梯只有四个按钮:开,关,上,下。上下的层数等于当前楼层上的那个数字。当然,如果不能满足要求,相应的按钮就会失灵。例如: 3,3,1,2,53, 3, 1, 2, 5 代表了 KiK_iK1=3K_1=3K2=3K_2=3,……),从 11 楼开始。在 11 楼,按“上”可以到 44 楼,按“下”是不起作用的,因为没有 2-2 楼。那么,从 AA 楼到 BB 楼至少要按几次按钮呢?

输入格式

共二行。

第一行为三个用空格隔开的正整数,表示 N,A,BN, A, B1N2001 \le N \le 2001A,BN1 \le A, B \le N)。

第二行为 NN 个用空格隔开的非负整数,表示 KiK_i

输出格式

一行,即最少按键次数,若无法到达,则输出 -1

样例 #1

样例输入 #1

5 1 5
3 3 1 2 5

样例输出 #1

3

提示

对于 100%100 \% 的数据,1N2001 \le N \le 2001A,BN1 \le A, B \le N0KiN0 \le K_i \le N

分析

好久之前其实就做过这一题,当时还是很废(当然现在也废),这也是一道经典BFSBFS,现在看这题就很清晰了,跟之前我写的那个调温度的相似,只不过这次选择多了而已,每次到一楼,就可以选择上下kik_i的楼层数,然后最后把cntbcntb输出,当然要注意特判一下(a=ba=b)的情况,输出0。

代码

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string> 
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <stack> 
#include <cmath>
#include <iomanip>
#define ll long long
#define AC return
#define Please 0
using namespace std;
const int N=210;
int n,k[N]; 
bool st[N];
typedef pair<int,int>PII;
typedef unsigned long long ull; 
int a,b,cnt[N]; 
inline int read(){//快读 
    int x=0,f=1;char ch=getchar();
    while(ch<'0' || ch>'9'){
        if(ch=='-') f=-1;
        ch=getchar();
    }
    while(ch>='0' && ch<='9'){
        x=x*10+ch-'0'; 
        ch=getchar();
    }
    AC x*f;
}
int d[2]={-1,1};
inline void bfs(){
	queue<int> q;
	q.push(a);
	cnt[a]=0;
	st[a]=0;
	while(q.size()){
		int t=q.front();
		q.pop();
		for(int i=0;i<2;i++){
			int now=t+k[t]*d[i];
			if(now>=1 && now<=n && st[now]==0){
				cnt[now]=cnt[t]+1;
				st[now]=1;
				q.push(now);
			}
		}
	}
}
int main(){
	cin>>n>>a>>b;
	for(int i=1;i<=n;i++){
		cin>>k[i];
	}
	memset(cnt,0x3f,sizeof cnt);
	memset(st,0,sizeof st);
	bfs();
	if(cnt[b]==0x3f3f3f3f) cout<<-1<<endl;
	else if(a==b) cout<<0<<endl; 
	else cout<<cnt[b]<<endl;
    AC Please;
}

希望能帮助到大家(QAQQAQ)!