• 洛谷P1135信息奥赛一本通1360 奇怪的电梯(lift)


    原题链接:

    洛谷 https://www.luogu.com.cn/problem/P1135

    信息奥赛一本通 http://ybt.ssoier.cn:8088/problem_show.php?pid=1360

    题目:

    1360:奇怪的电梯(lift)


    时间限制: 1000 ms         内存限制: 65536 KB
    提交数: 4824     通过数: 2058

    【题目描述】

    大楼的每一层楼都可以停电梯,而且第i层楼1iN上有一个数字Ki(0≤=Ki≤=N。电梯只有四个按钮:开,关,上,下。上下的层数等于当前楼层上的那个数字。当然,如果不能满足要求,相应的按钮就会失灵。例如:3 3 1 2 5代表了KiK1=3,K2=3,,从一楼开始。在一楼,按“上”可以到4楼,按“下”是不起作用的,因为没有−2楼。那么,从A楼到B楼至少要按几次按钮呢?

    【输入】

    共有二行,第一行为三个用空格隔开的正整数,表示N,A,B(1N200,1A,BN),第二行为N个用空格隔开的正整数,表示Ki

    【输出】

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

    【输入样例】

    5 1 5
    3 3 1 2 5
    

    【输出样例】

    3



    这是一道搜索题,这里可以运用广搜。
    首先写一个队列a,h代表当前在几楼,C代表走了几步。
    初始化就是先将初始楼层加入队列,
    搜索过程就是讲队首元素取出,然后将在对首元素所在楼层按键后所能到达的楼层加入队尾,并且次数加一,如果到达指定楼层就输出次数,最后head++继续搜下一个,
    循环条件就是队列非空,即head<=tail,
    如果循环结束还没到达指定楼层就代表无法到达,输出-1。

    代码:
    c:
    #include<stdio.h>
    struct k{
        int h,c;//h代表当前在几楼,C代表走了几步
    }a[201];//广搜队列 
    int b[201];//存储数据 
    int ye[201];//记录楼层是否到达 
    int m,n,r,s;
    int head,tail;
    int main(){
        scanf("%d%d%d",&n,&r,&s);
        for(int i=1;i<=n;i++)scanf("%d",b+i);
        if(r==s){printf("0");return 0;}//如果初始楼层和目标楼层相同则不用走 
        a[0].h=r;a[0].c=0;// 初始楼层加入队列
        tail=head=0;
        while(head<=tail){//广搜 ,循环条件就是队列非空
            if(a[head].h+b[a[head].h]<=n&&ye[a[head].h+b[a[head].h]]==0){//向上走 
                ye[a[head].h+b[a[head].h]]=1;//记录该楼层已经走过 
                a[++tail].h=a[head].h+b[a[head].h];//楼层按键后所能到达的楼层加入队尾 
                a[tail].c=a[head].c+1;//并且次数加一
                if(a[tail].h==s){printf("%d",a[tail].c);return 0;}//如果到达指定楼层就输出次数
                }
            if(a[head].h-b[a[head].h]>=1&&ye[a[head].h-b[a[head].h]]==0){//向下走 
                ye[a[head].h-b[a[head].h]]=1;//记录该楼层已经走过 
                a[++tail].h=a[head].h-b[a[head].h];//楼层按键后所能到达的楼层加入队尾 
                a[tail].c=a[head].c+1;//并且次数加一
                if(a[tail].h==s){printf("%d",a[tail].c);return 0;}//如果到达指定楼层就输出次数
                }
        head++;//对首加1 
        }
        printf("-1");return 0;//如果循环结束还没到达指定楼层就代表无法到达,输出-1
    }

    pascal:

    type k=record
        h:longint;
        c:longint;//h代表当前在几楼,C代表走了几步
    end;
    var
        a:array[0..200]of k;//广搜队列 
        b:array[1..200]of longint;//存储数据 
        ye:array[1..200]of boolean;//记录楼层是否到达 
        m:longint;
        n:longint;
        r:longint;
        s:longint;
        head:longint;
        tail:longint;
        i:longint;
    begin
        read(n,r,s);
        for i:=1 to n do read(b[i]);
        if r=s then begin
            writeln(0);exit();//如果初始楼层和目标楼层相同则不用走
        end;
        a[0].h:=r;a[0].c:=0; // 初始楼层加入队列
        head:=0;tail:=head;
        while head<=tail do begin //广搜 ,循环条件就是队列非空
            if (a[head].h+b[a[head].h]<=n)and(ye[a[head].h+b[a[head].h]]=false)then begin //向上走
                ye[a[head].h+b[a[head].h]]:=true;//记录该楼层已经走过
                tail:=tail+1;
                a[tail].h:=a[head].h+b[a[head].h]; //楼层按键后所能到达的楼层加入队尾 
                a[tail].c:=a[head].c+1;//并且次数加一
                if a[tail].h=s then begin 
                    writeln(a[tail].c);exit();//如果到达指定楼层就输出次数
                end;
            end;
            if (a[head].h-b[a[head].h]>=1)and(ye[a[head].h-b[a[head].h]]=false)then begin //向下走 
                ye[a[head].h-b[a[head].h]]:=true;//记录该楼层已经走过
                tail:=tail+1;
                a[tail].h:=a[head].h-b[a[head].h]; //楼层按键后所能到达的楼层加入队尾 
                a[tail].c:=a[head].c+1;//并且次数加一
                if a[tail].h=s then begin
                    writeln(a[tail].c);exit();//如果到达指定楼层就输出次数
                end;
            end;
            head:=head+1;//对首加1 
        end;
        writeln(-1);//如果循环结束还没到达指定楼层就代表无法到达,输出-1
    end.

    我可能写的不好,如果有问题,请指出,谢谢。

  • 相关阅读:
    vba的单元格引用的总结
    为IE窗口添加菜单实例
    给SQLServer2000升级遇到的问题
    图片上传问题(含网页图片预览)
    javascript小技巧【待续】
    成功部署JSP网站的经验总结
    VBA实例
    为JDK增加新的jar包
    理解绝对定位和相对定位布局
    资源收集
  • 原文地址:https://www.cnblogs.com/sy666/p/12403973.html
Copyright © 2020-2023  润新知