【深度優先搜索DFS】奇怪的電梯

原題出處:洛谷題單

題目:奇怪的電梯

呵呵,有一天我做了一個夢,夢見了一種很奇怪的電梯。大樓的每一層樓都可以停電梯,而且第ii層樓(1 \le i \le N)(1≤i≤N)上有一個數字K_i(0 \le K_i \le N)K i (0≤K i ≤N)。電梯只有四個按鈕:開,關,上,下。上下的層數等於當前樓層上的那個數字。當然,如果不能滿足要求,相應的按鈕就會失靈。例如:3, 3 ,1 ,2 ,53,3,1,2,5代表了K_i(K_1=3,K_2=3,…)K
i (K 1=3,K 2 =3,…),從11樓開始。在11樓,按“上”可以到44樓,按“下”是不起作用的,因爲沒有-2−2樓。那麼,從AA樓到BB樓至少要按幾次按鈕呢?

輸入格式

共二行。

第一行爲33個用空格隔開的正整數,表示N,A,B(1≤N≤200, 1≤A,B≤N)N,A,B(1≤N≤200,1≤A,B≤N)。

第二行爲N個用空格隔開的非負整數,表示Ki。

輸出格式

一行,即最少按鍵次數,若無法到達,則輸出−1。

輸入輸出樣例
輸入 #1
5 1 5
3 3 1 2 5
輸出 #1
3

DFS解法:

1、首先得把題意看懂了,一共n層樓,要從A曾到達B層,因爲電梯的特殊規則,所以,在嘗試的時候,可能會遇到無法到達或者多種方式到達的情況,如果把特殊情況考慮到位起碼可以得到20分:

第一種:A=B時,輸出是0 (10分)

第二種:所有樓層都試了就是沒有一條能到達B,那麼cnt就始終等於它的初始值,這裏你要賦給它一個很大的初始值。(10分)

2、用搜索的思想來解決,就比較簡單了直接套用dfs的搜索框架就行了
(我寫完到這裏的時候,有兩個測試點超時了)

3、解決超時問題就得想想怎麼樣來簡化它,第一,我要找最小值,所以如果在搜索過程中出現的案件次數已經比我之前存好的cnt大了,那麼這個時候就沒必要沿着這條路走了可以直接return,到這裏ok了,可以AC。

#include<bits/stdc++.h>
using namespace std;

int n,A,B,cnt=100001;
int k[210];
bool b[210]={0};//標記樓層是否已經走過 
int d[2]={1,-1};//上樓加,下樓減 

void dfs(int x,int s)
{
	if(x==B) cnt=min(s,cnt);//如果已經到達了 
	if(s>cnt) return;//如果s大於cnt就不用再繼續了,我們要找的是最小值 
	//下面是典型的dfs 
	for(int i=0;i<2;i++){
		int xx=x+d[i]*k[x];
		if(xx>=1 && xx<= n && b[xx]){
			s++;
			b[x]=false;
                        dfs(xx,s);
			b[x]=true;//回溯 
			s--;//回溯 
		}
	 } 	 
}

int main(){
	cin>>n>>A>>B;
	
	memset(b,true,sizeof(b));
	for(int i=1;i<=n;i++) cin>>k[i];
	
	b[A]=false;//標記出發樓層 ,這裏是容易忽略的哦 
	if(A==B) cnt=0;//注意:如果當前樓層和要到達的樓層是一樣的cnt=0 
	else dfs(A,0);
	if(cnt==100001) cout<<-1;//注意:如果cnt這這個值的話說明沒有找到一條路徑,這裏因爲數值範圍小,所以100001肯定夠了 
	else cout<<cnt;
	return 0;
} 

BFS解法見下一篇博文:這道題的BFS解法,簡單易懂

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章