目录见右上
站内文章欢迎各位转载,但是请注明出处(毕竟码字很辛苦哈)。

主题

奇怪的电梯

(原题连接:权限限制没有链接)

呵呵,有一天我做了一个梦,梦见了一种很奇怪的电梯。大楼的每一层楼都可以停电梯,而且第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。

样例

LIFT.IN

5 1 5

3 3 1 2 5

LIFT.OUT

3


个人解法:

这是一个比较easy的题了。其实我在考场上想的的跑最短路,对于每一层,对于它可以到达的楼层建一条边。之后dijkstral一趟求答案。

我还可以再蒟蒻一点吗?

虽然这一波数据e<=400,n<=200,最短路是很简单的。SPFA大概跑个O(e),dijkstral的O(n^2)都可以轻松过,都不至于加一个堆优化。

显然还是有更优的算法的。

毕竟每一个建了一个图之后,要求的是边权为1的最短路,倒不如O(n)的BFS跑得快。所以可以直接O(n)跑BFS遍历这张图。

然而考场上蒟蒻的我只想出了dijkstral。而且!dijkstral还打错了……导致丢了10分。诶


代码如下(dijkstral):

var

k,dist:array[1..201] of longint;

w:array[1..201,1..201] of longint;

flag:array[1..201] of boolean;

n,i,j,s,t:longint;


procedure dijkstral(i:longint);//dijkstral跑最短路

var

  vi,vj,minn,p:longint;

begin

  flag[i]:=true;

  for vi:=1 to n do

   dist[vi]:=w[i,vi];

  for vi:=1 to n-1 do

  begin

   minn:=400;

   for vj:=1 to n do

    if not flag[vj] and (dist[vj]<=minn) then//显然如果写dist[vj]<minn就bomb了。这样一来p不会赋值,可能在第一次寻找p的时候就找不到(边权相同的情况)一个最小的p来更新minn。然后就愉悦地被卡掉了。

    begin

     minn:=dist[vj];

     p:=vj;

    end;

   flag[p]:=true;

   for vj:=1 to n do

    if dist[vj]>dist[p]+w[p,vj] then dist[vj]:=dist[p]+w[p,vj];

  end;

end;


begin

read(n,s,t);

for i:=1 to n do

  read(k[i]);

for i:=1 to n do

begin

  if i+k[i]<=n then w[i,i+k[i]]:=1;

  if i-k[i]>=1 then w[i,i-k[i]]:=1;//读入与建图

end;

for i:=1 to n do

  for j:=1 to n do

   if w[i,j]=0 then w[i,j]:=400;

for i:=1 to n do

  w[i,i]:=0;


dijkstral(s);//跑一趟最短路


if dist[t]<>400 then writeln(dist[t])//输出

  else writeln('-1');

end.


我还说什么好?我已经简直了……

评论
©主题 —— Powered by LOFTER