问题 D: 电梯

问题 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

来源

代码实现
第一种:
<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 ;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值