(提早聲明,本篇博客可能質量不如前幾篇好,畢竟連肝四篇博客我已經快吐血了✿◕‿◕✿)ios
看到這道題,第一時間想到的就是:深搜!!數組
因而我打了一個只能獲得20分,剩下都MLE的深搜代碼:函數
#include<iostream> #include<cstdio> using namespace std; int n,m[210],a,b,xq=0,minn=9999; void dfs(int idx,int cishu){ if(idx==b){ xq=1;//若是到達了我麼就用小旗標記一下,以便於最後輸出 minn=min(minn,cishu);//每次到達想要的那個樓層時,都要取最小值,這樣咱們就能夠獲得只要要按幾回按鈕了。 return; } //由於在每一層能作的操做只有兩個,因此咱們作兩個判斷就夠了,若是不越界的話,進行深搜就好啦(●'◡'●) if(idx-m[idx]>0){ dfs(idx-m[idx],cishu+1); } if(idx+m[idx]<=n){ dfs(idx+m[idx],cishu+1); } } int main(){ scanf("%d%d%d",&n,&a,&b); for(int i=1;i<=n;i++){ scanf("%d",&m[i]); }//以上全是輸入 dfs(a,0);//調用深搜函數 if(xq!=0) printf("%d\n",minn);//輸出,若是小旗不等於零就說明咱們到達過第b層樓 else printf("-1\n");//不然,也就是沒有到達過第b層樓,就按照題目要求輸出-1 return 0;//不要忘記return 0喔 }
MLE是什麼來着?讓咱們百度一下:優化
看到這裏你還不知道該幹什麼嗎!俗話說,優化是個好東西spa
咱們來用一個數組,把咱們判斷過的標記上,而後下次再判斷到這個點咱們就先看這個點有沒有被標記,若是被標記了那也就不用繼續下去了,反正已經判斷過了。code
//數組定義個1000就好啦,反正數據也不大 hh[idx]=1;//每次hh[idx]都等於1,而後後面進行深搜的時候它就不會被搜到嘍,能夠節省很多時間呢 if(idx-m[idx]>0&&hh[idx-m[idx]]==0){//判斷idx-m[idx]是否被算過 dfs(idx-m[idx],cishu+1);//若是沒有被計算過,那麼idx-m[idx],次數+1啦 } if(idx+m[idx]>0&&hh[idx+m[idx]]==0){//判斷idx+m[idx]是否被算過 dfs(idx+m[idx],cishu+1);//跟上面同樣,若是沒有被計算過,那麼idx+m[idx],次數+1啦 } hh[idx]=0;//最後不要忘了歸零!很重要的! //若是你不歸零會影響到後面計算,可能明明這一條路是最小的次數,結果就由於你忘了歸零,成功錯過正確答案
可是這樣只有80分......咱們還能怎麼優化呢?blog
若是當前的次數已經大於minn了呢......那麼繼續算下去不久沒有意義了?ci
那咱們就再加一個判斷條件:博客
hh[idx]=1; if(idx-m[idx]>0&&cishu<minn&&hh[idx-m[idx]]==0){ //加上這個特判就萬事大吉了!若是當前次數已經大於等於minn那繼續算下去就沒有意義了,反正算到最後minn仍是不變,因此咱們只在當前次數小於minn的時候纔算下去 dfs(idx-m[idx],cishu+1); } if(idx+m[idx]>0&&cishu<minn&&hh[idx+m[idx]]==0){ //這個跟上面那個道理是同樣的啦 dfs(idx+m[idx],cishu+1); } hh[idx]=0;
最後獻上完整代碼:io
#include<iostream> #include<cstdio> using namespace std; int n,m[210],a,b,xq=0,minn=9999,hh[1010];//minn不能等於很小,否則跟其餘的比小他最小怎麼辦 void dfs(int idx,int cishu){//深搜函數 if(idx==b){//出口,若是當前樓層就是第b層,那麼就讓小旗標記一下,取按鍵次數的最小值,而後返回 xq=1; minn=min(minn,cishu); return; } hh[idx]=1;//標記idx if(idx-m[idx]>0&&cishu<minn&&hh[idx-m[idx]]==0){ //次數若是大於等於minn那麼計算下去就沒意義了,反正算到最後minn不會有變化 //若是hh數組的第idx-m[idx]項沒有被標記,也就是說他沒有被判斷過,咱們就能夠繼續了 dfs(idx-m[idx],cishu+1);//進行深搜,次數每次加一不要忘 } if(idx+m[idx]>0&&cishu<minn&&hh[idx+m[idx]]==0){//這個判斷跟上一個是同樣的,不過一個加一個減 dfs(idx+m[idx],cishu+1);//進行深搜,注意這裏是+而不是- } hh[idx]=0;//取消標記 return;//返回上一層 } int main(){ scanf("%d%d%d",&n,&a,&b); for(int i=1;i<=n;i++){ scanf("%d",&m[i]); }//以上爲輸入 dfs(a,0);//調用函數 if(xq!=0) printf("%d\n",minn);//輸出,小旗若是不等於0也就表示咱們到達過第b層,輸出minn就行了 else printf("-1\n");//不然小旗等於0,也就是說咱們從未到達過第b層,按照題目要求輸出-1 return 0; }