HDU1548 A strange lift(BFS或Dijkstra)

题目大意

有一个奇怪的电梯,他的每一层都只能去往固定的一层,不能随意去往任意一层。
每一层都对应一个数字,假设第i层对应k,那么含义为:在第i层的电梯下一次移动只能移向i+k层或i-k层。问至少移动多少次,可以从第A层移动到第B层。

两种思路:
一是广搜,从A层开始向外扩展,查找到达“临近”的层数的最少步数,直到找到B层,即为答案。需要将给定的k转化成第i层可以去往的i+k或i-k,注意记得判断越界访问标记就可以了。
二是最短路算法,这里用的是Dijkstra算法,也是裸裸的,很容易敲。但是!!!我WA了好多发,最后和网上很多代码对比之后发现少了一句话,加上这句话就A了。

	dis[a]=0;

dis数组是从A层到任意一层的最少步数。dis[a]即从A到A层的步数为0。我在写代码的时候忘记判断这个特殊情况,估计是被卡了。所以以后要注意特判啊!!!

BFS AC代码

#include<stdio.h>
#include<string.h>
#include<queue>
#include<algorithm>
#include<math.h>
#define maxn 205
using namespace std;
struct node{
    int f;
    int step;
    node(int f=0,int step=0):f(f),step(step){}
};
int main()
{
    int n,a,b;
    int next[maxn];
    bool book[maxn];
    queue<node> q;
    while(~scanf("%d",&n))
    {
        if(n==0)
            break;
        scanf("%d%d",&a,&b);
        while(!q.empty())
            q.pop();
        bool success=false;
        memset(book,false,sizeof(book));

        for(int i=1;i<=n;i++)
            scanf("%d",&next[i]);
        q.push(node(a,0));
        book[a]=true;
        while(!q.empty()){
            node temp=q.front();
            q.pop();
            if(temp.f==b){
                printf("%d\n",temp.step);
                success=true;
                break;
            }
            if(temp.f+next[temp.f]<=n&&book[temp.f+next[temp.f]]==false){
                book[temp.f+next[temp.f]]=true;
                q.push(node(temp.f+next[temp.f],temp.step+1));
            }
            if(temp.f-next[temp.f]>=1&&book[temp.f-next[temp.f]]==false){
                book[temp.f-next[temp.f]]=true;
                q.push(node(temp.f-next[temp.f],temp.step+1));
            }
        }
        if(!success)printf("-1\n");

    }
    return 0;
}

Dijkstra AC代码

#include<stdio.h>
#include<algorithm>
#include<math.h>
using namespace std;
#define maxn 205
#define inf 999999
int maze[maxn][maxn];
int dis[maxn];
void init()
{
    for(int i=0;i<maxn;i++){
        for(int j=0;j<maxn;j++)
            maze[i][j]=inf;
        dis[i]=inf;
    }
}
int main()
{
    int n,a,b;
    int u;
    bool book[maxn];
    while(1)
    {   scanf("%d",&n);
        if(n==0)
            break;
        scanf("%d%d",&a,&b);
        init();
        for(int i=1;i<=n;i++){
            int temp;
            scanf("%d",&temp);
            if(i+temp<=n)
                maze[i][i+temp]=1;
            if(i-temp>=1)
                maze[i][i-temp]=1;
        }
        for(int i=1;i<=n;i++){
            dis[i]=maze[a][i];
            book[i]=false;
        }
        dis[a]=0;///*****************************
        book[a]=true;
        int minx;
        for(int i=1;i<n;i++){
            ///找到距离a最近的点
            minx=inf;
            for(int j=1;j<=n;j++){
                if(!book[j]&&dis[j]<minx){
                    minx=dis[j];
                    u=j;
                }
            }
            if(minx==inf)
                break;
            book[u]=true;

            ///根据这个找到的最近的点进行松弛
            for(int j=1;j<=n;j++){
                //if(maze[u][j]<inf)
                if(dis[j]>dis[u]+maze[u][j]&&!book[j])
                    dis[j]=dis[u]+maze[u][j];
            }
        }
        if(dis[b]==inf) printf("-1\n");
        else printf("%d\n",dis[b]);

    }
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值