1. 程式人生 > >JZOJ 3.25 1422——【汕頭市選2012初中組】步行(walk)

JZOJ 3.25 1422——【汕頭市選2012初中組】步行(walk)

題目描述

ftiasch 又開發了一個奇怪的遊戲,這個遊戲是這樣的:有N 個格子排成一列,每個格子上有一個數

字,第i 個格子的數字記為Ai。這個遊戲有2 種操作:

  1. 如果現在在第i 個格子,則可以跳到第Ai 個格子。

  2. 把某個Ai 增加或減少1。

nm 開始在第1 個格子,他需要走到第N 個格子才能通關。現在他已經頭昏腦漲啦,需要你幫助他

求出,從起點到終點最少需要多少次操作。

輸入

第1 行,1 個整數N。第2 行,N 個整數Ai。

輸出

第1 行,1 個整數,表示最少的操作次數。

樣例輸入

5

3 4 2 5 3

樣例輸出

3

資料範圍

• 對於30% 的資料,1<= N <= 10。

• 對於60% 的資料,1<= N <= 1 000。

• 對於100% 的資料,1 <= N<= 100000,1 <= Ai <= N。

其實這是一道bfs題。
用v陣列來儲存有沒有走過;用father陣列來記錄到i最少的運算元;用state陣列來記錄i到了那個位置。
然後再三種情況模擬

程式碼如下:

var father,a:array[0..100001]of int64;
    n,i:longint;

procedure bfs;
var head,tail,x:longint;
    v,state:array[0..100001]of int64;
begin
fillchar(v,sizeof(v),#0); fillchar(state,sizeof(state),#0); fillchar(father,sizeof(father),#0); head:=1; tail:=1; v[a[1]]:=1; father[a[1]]:=1; state[1]:=a[1]; while (head<=tail) do begin x:=state[head]; if x=n then exit; if v[a[x]]=0 then begin inc(tail); v[a[x]]:=1
; state[tail]:=a[x]; father[a[x]]:=father[x]+1; end; if (v[x+1]=0)and(x<n) then begin inc(tail); v[x+1]:=1; state[tail]:=x+1; father[x+1]:=father[x]+1; end; if (v[x-1]=0)and(x>0) then begin inc(tail); v[x-1]:=1; state[tail]:=x-1; father[x-1]:=father[x]+1; end; inc(head); end; end; begin assign(input,'walk.in'); assign(output,'walk.out'); reset(input); rewrite(output); readln(n); for i:=1 to n do read(a[i]); if i=1 then begin write(0); halt; end; bfs; writeln(father[n]); close(input); close(output); end.