f166. 傳送點
解題
題目提到可以向左移動$L$格,跟向右移動$R$格,並且踩到的位置會進行傳送到對應的索引值$S_i$,並且不會二次傳送
我們可以用bfs為基底去做跳動的運算,這樣可以擴散我們走過的路徑,並且在走過的索引值上打上標記(走過的不走)避免無限迴圈,如果現在讀到的點是目標點,則跳出迴圈,並且輸出走過的路,如果執行到最後依然沒找到就回傳$-1$
如何做到計算層數的?
利用for迴圈,每次執行當前剛從while迴圈下來的長度次數,這就代表著這層的所有結點,只要把這層的節點全部走完就是距離+1
AC Code
python
from sys import stdin
from collections import deque
n,p,l,r=map(int,stdin.readline().strip().split())
row=list(map(int,stdin.readline().strip().split()))
def bfs():
walk=[False]*n
walk[0]=True
q=deque([0])
walks=0
while q:
temp=deque([])
for _ in range(len(q)):
idx=q.popleft()
if idx==p: return walks
if 0<=idx-l<n and 0<=row[idx-l]<n and not(walk[idx-l]):
temp.append(row[idx-l])
walk[idx-l]=True
if 0<=idx+r<n and 0<=row[idx+r]<n and not(walk[idx+r]):
temp.append(row[idx+r])
walk[idx+r]=True
q=temp
walks+=1
return -1
if p==0:
print(p)
else:
print(bfs())
C++
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,p,l,r;
ll bfs(const vector<ll>& rows){
vector<bool> walk(n);
for(ll i=0;i<n;i++) walk[i]=false;
walk[0]=true;
ll walks=0;
queue<ll> q;
q.push(0);
while(!q.empty()){
queue<ll> temp;
ll sz=q.size();
for(ll i=0;i<sz;i++){
ll idx=q.front();
q.pop();
if(idx==p) return walks;
if(0<=idx-l && 0<=rows[idx-l] && rows[idx-l]<n && !walk[idx-l]){
temp.push(rows[idx-l]);
walk[idx-l]=true;
}
if(idx+r<n && 0<=rows[idx+r] && rows[idx+r]<n && !walk[idx+r]){
temp.push(rows[idx+r]);
walk[idx+r]=true;
}
}
walks++;
q=temp;
}
return -1;
}
int main(){
cin>>n>>p>>l>>r;
vector<ll> row(n);
for(ll i=0;i<n;i++){
cin>>row[i];
}
if(p==0) cout<<p<<endl;
else cout<<bfs(row)<<endl;
}