问题 D: 电梯
时间限制: 1 Sec 内存限制: 128 MB提交: 42 解决: 9
题目描述
实验楼有一部神秘的电梯,它只有“上”和“下”两个按钮,实验楼的每一层都标有一个值K,第i层的值为Ki,如果按了“上”按钮,会从第i层升到第i+Ki层;如果按了“下”按钮则会从第i层降到第i-Ki层,已知能到的层数为1到N层,GX想从第A层上到第B层,现在给你N,A,B和一串数K1到Kn,请求出GX从A到B,至少按下多少个按钮。
输入
第一行输入N,A,B( 1 <= N,A,B <= 300) ,表示实验楼共有N层,起点为A,终点为B
第二行输入N个数,表示K1到Kn
输出
对于每组数据,输出一个数,表示GX从A到B,至少按下多少个按钮,如果GX无法到达B,请输出-1.
样例输入
5 1 5
3 3 1 2 5
样例输出
3
来源
XCOJ
2015-2016学年第一次测试赛
代码实现
第一种:
<span style=" color: rgb(255, 0, 0);"><strong>//只找到一种实现方法,没有实现最短</strong></span><strong>
</strong>#include "iostream"
#include "cstring"
using namespace std;
int N,A,B,j/*所走次数*/;
int Find(int *P,int *Q)
{
int m=A+P[A],n=A-P[A];
if(A==B)
return 0;
else if(Q[m]&&n<1||Q[n]&&m>N||Q[n]==1&&Q[m]==1)
return -1;
else if(n>0&&Q[n]!=1)
{
A=n;
Q[A]=1;
j++;
if(A==B)
return j;
Find(P,Q);
}
else if(m<=N&&Q[m]!=1)
{
A=m;
Q[A]=1;
j++;
if(A==B)
return j;
Find(P,Q);
}
}
int main()
{
while(cin>>N>>A>>B)
{
j=0;
int P[N+1],Q[N+1]/*标记这个位置是否走过*/;
memset(Q,0,sizeof(Q));
Q[A]=1;
for(int i=1;i<=N;i++)
cin>>P[i];//各个楼层能上或下的层数
cout<<Find(P,Q)<<endl;
}
return 0;
}
第二种(完整的):
# include <iostream>
# include <cstdio>
# include <cstring>
# include <algorithm>
# include <cmath>
# define LL long long
using namespace std ;
const int MAXN=300;
const int INF=0x3f3f3f3f;
int n ;
bool vis[MAXN];
int cost[MAXN][MAXN] ;
int lowcost[MAXN] ;
int pre[MAXN];
void Dijkstra(int beg)
{
for(int i=0;i<n;i++)
{
lowcost[i]=INF;vis[i]=false;pre[i]=-1;
}
lowcost[beg]=0;
for(int j=0;j<n;j++)
{
int k=-1;
int Min=INF;
for(int i=0;i<n;i++)
if(!vis[i]&&lowcost[i]<Min)
{
Min=lowcost[i];
k=i;
}
if(k==-1)
break ;
vis[k]=true;
for(int i=0;i<n;i++)
if(!vis[i]&&lowcost[k]+cost[k][i]<lowcost[i])
{
lowcost[i]=lowcost[k]+cost[k][i];
pre[i]=k;
}
}
}
int main ()
{
while (scanf("%d" , &n ) !=EOF)
{
int i,j;
for (i=0;i<n;i++)
for (j=0;j<n;j++)
{
if (i==j)
cost[i][j]=0 ;
else
cost[i][j]=INF ;
}
int s , e , t;
scanf("%d %d" , &s , &e) ;
for (i = 0 ; i < n ; i++)
{
scanf("%d" , &t) ;
if (i + t <= n-1)
cost[i][i+t] = 1 ;
if (i - t >= 0)
cost[i][i-t] = 1 ;
}
Dijkstra(s-1) ;
if (lowcost[e-1] != INF)
printf("%d\n" , lowcost[e-1]) ;
else
printf("-1\n") ;
}
return 0 ;
}