码迷,mamicode.com
首页 > 其他好文 > 详细

洛谷【P1135】奇怪的电梯 解题报告

时间:2016-08-13 19:28:39      阅读:144      评论:0      收藏:0      [点我收藏+]

标签:

【传送门】:http://www.luogu.org/problem/show?pid=1135

---------------------------------------------------题目----------------------------------------------------------

题目描述

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

输入输出格式

输入格式:

    输入文件共有二行,第一行为三个用空格隔开的正整数,表示N,A,B(1≤N≤200, 1≤A,B≤N),第二行为N个用空格隔开的正整数,表示Ki。

输出格式:

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

输入输出样例

输入样例#1:

LIFT.IN
5 1 5
3 3 1 2 5

输出样例#1:

LIFT.OUT
3

-------------------------------------------------解题过程--------------------------------------------------------

刚开始写的BFS 拿了80分,错了两个测试点,虽然那个PIN好像有点多余,但还是懒得删QAQ,

//初始代码(BFS版)
var
  head,tail:longint;  //对头对尾指针
  temp:longint;     
  i,n,a,b,sum:longint;  
  num:array[1..200] of longint;
  f:array[0..201] of record   //记录类型,data用于记录队列里的数,pin用于记录已经走了几次
                   data:longint;
                   pin:shortint;
                 end;
  boo:array[1..200] of boolean;
//-------------------------------------------------
procedure printf(uuu:longint);    //输出过程
begin
  writeln(f[uuu].pin);      halt;
end;
//-------------------------------------------------
begin
  readln(n,a,b);    
  for i:= 1 to n do read(num[i]);   //输出过程
  if a=b then begin                 //如果起点等于终点就输出0
              writeln(0);
              halt;
           end;
  sum:=n;               //sum用于记录剩余可走的层数
  head:=0;   tail:=1;    fillchar(boo,sizeof(boo),true);    //初始化
  f[1].data:=a;    f[1].pin:=0;   boo[1]:=false;    dec(sum);      //错误就在这一行   
//BFS开始--------------------------------------------------------------------                  
  while head<tail do
  begin
    inc(head);   
    temp:=f[head].data+num[f[head].data];    //往上走
    if (temp>=1) and (temp<=n) and (boo[temp]) then  
      begin
        if sum=0 then   begin   writeln(-1); halt;  end;     //这个有点鸡肋,不过懒得删
        inc(tail);     f[tail].data:=temp;     f[tail].pin:=f[head].pin+1;      
        boo[temp]:=false;       dec(sum);
        if temp=b then printf(tail);     //到达指定楼层就输出
      end;
    temp:=f[head].data-num[f[head].data];   //往下走
    if (temp>=1) and (temp<=n) and (boo[temp]) then  
      begin                                     //同上
        if sum=0 then   begin   writeln(-1); halt;  end;   
        inc(tail);    f[tail].data:=temp;       f[tail].pin:=f[head].pin+1; 
        boo[temp]:=false;       dec(sum);
        if temp=b then printf(tail);
      end;
  end;
//BFS结束--------------------------------------------------------------------
  writeln(-1);    //当BFS后发现没办法到达输出 -1
end.

       两个错的测试点,一个是因为我用了shortint(退shortint报平安~),还有一个是因为弄错了初始化的时候给boo布尔数组的赋值下标(详见第27行)

      正确的BFS版本如下:

//正确代码(BFS版)
var
  head,tail:longint;   //对头对尾指针
  temp:longint;
  i,n,a,b,sum:longint;
  num:array[1..200] of longint;
  f:array[0..201] of record  //记录类型,data用于记录队列里的数,pin用于记录已经走了几次
                        data:longint;
                        pin:integer;    //拒绝shortint,从我做起……
                      end;
  boo:array[1..200] of boolean;
//-------------------------------------------------
procedure printf(uuu:longint);  //输出过程
begin
  writeln(f[uuu].pin);      halt;
end;
//-------------------------------------------------
begin
  readln(n,a,b);
  for i:= 1 to n do read(num[i]);    //输出过程
  if a=b then begin          //如果起点等于终点就输出0
               writeln(0);
               halt;
           end;
  sum:=n;    //sum用于记录剩余可走的层数【鸡肋……】
  head:=0;   tail:=1;    fillchar(boo,sizeof(boo),true); 
  f[1].data:=a;    f[1].pin:=0;   boo[a]:=false;    dec(sum);     //已更正错误     
//BFS开始--------------------------------------------------------------------                  
  while head<tail do
  begin
    inc(head);
    temp:=f[head].data+num[f[head].data];    //往上走
    if (temp<=n) and (boo[temp]) then  
      begin  
        if sum=0 then   begin   writeln(-1);   halt;  end;     //这个有点鸡肋,不过懒得删
        inc(tail);     f[tail].data:=temp;     f[tail].pin:=f[head].pin+1;
        boo[temp]:=false;       dec(sum);
        if temp=b then printf(tail);          //到达指定楼层就输出
      end;
    temp:=f[head].data-num[f[head].data];   //往下走
    if (temp>0) and (boo[temp]) then  
      begin                               //同上
        if sum=0 then   begin   writeln(-1);   halt;  end;  
        inc(tail);    f[tail].data:=temp;       f[tail].pin:=f[head].pin+1; 
        boo[temp]:=false;       dec(sum);
        if temp=b then printf(tail);
      end;
  end;
//BFS结束--------------------------------------------------------------------
  writeln(-1);   //当BFS后发现没办法到达输出 -1
end.

  题目的标签是递推,但我只会用广搜……不过还是勉强AC了

洛谷【P1135】奇怪的电梯 解题报告

标签:

原文地址:http://www.cnblogs.com/tonylim/p/5768516.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!