【題目鏈接:NYOJ-58】
經典的搜索問題,想必這題用廣搜的會比較多,所以我首先使的也是廣搜,但其實深搜同樣也是可以的。
不考慮剪枝的話,兩種方法實踐消耗相同,但是深搜相比廣搜內存低一點。
我想,因為廣搜需要的就是隊列,所以相比遞歸隊列更耗內存?
當然DFS並不像上圖所說,需要用棧,而是運用遞歸即可。
BFS:
因為BFS是要一個接一個的遍歷,所以用到了結構體,來保存坐標和當前所走步數
1.每走一步,通過定義的結構體,從隊列中提取a(即上一步的坐標、步數(步數每次累加))
2.在a的基礎上進行對a周圍四個方向進行判斷,找出可以繼續走的位置(即非障礙、邊界),並將該位置的坐標,進入隊列中
繼續走下一步時,循環以上1.2兩步操作
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 using namespace std; 7 int dir[4][2]= {1,0,-1,0,0,1,0,-1}; 8 struct point{ 9 int x,y,step; 10 }; 11 int bfs(point s,point e,int map[9][9]){ 12 queue<point>tp;//自定義類型的隊列 13 int i; 14 point t;//保存當前坐標 ,臨時變量 15 //s表示之前 16 //e表示目標 17 s.step=0;//保存步數 18 map[s.x][s.y]=1;//標記此處已經走過 19 tp.push(s);//初始化隊列 ,s中(x,y)初始為起始坐標,step = 0 20 while(!tp.empty()){//循環直至隊列為空 21 s=tp.front();//每次循環s都等於隊首 22 tp.pop();//刪除隊首 23 if(s.x==e.x&&s.y==e.y)//如果當前坐標與目標坐標相等 24 return s.step; //返回當前的步數 25 //遍歷四個不同的方向 26 //如果是通道(0),即增加步數 27 for(int i=0; i<4; i++){ 28 t.x=s.x+dir[i][0]; 29 t.y=s.y+dir[i][1]; 30 if(map[t.x][t.y]==0){//如果是通道 31 t.step=s.step+1; 32 map[t.x][t.y]=1;//標記此處已經走過,及標記為牆 33 tp.push(t); 34 } 35 } 36 } 37 } 38 int main(){ 39 int t; 40 scanf("%d",&t); 41 while(t--){ 42 point s,e; 43 int map[9][9]= {1,1,1,1,1,1,1,1,1, 44 1,0,0,1,0,0,1,0,1, 45 1,0,0,1,1,0,0,0,1, 46 1,0,1,0,1,1,0,1,1, 47 1,0,0,0,0,1,0,0,1, 48 1,1,0,1,0,1,0,0,1, 49 1,1,0,1,0,1,0,0,1, 50 1,1,0,1,0,0,0,0,1, 51 1,1,1,1,1,1,1,1,1,}; 52 scanf("%d%d%d%d",&s.x,&s.y,&e.x,&e.y); 53 printf("%d\n",bfs(s,e,map)); 54 } 55 return 0; 56 }
DFS:
DFS就沒什么好說了,不明白可以看看之前的DFS博客
只不過這里,沒有用到單獨的二維數組see[][],來判斷本個坐標是已經搜索過
而是結合題意,把當前所在位置變為'1',即障礙、邊界,那么在遞歸往下延伸判斷四周時,達到同樣的目的
當然在DFS函數最后,需要把Map[][]重新變為'0',因為遞歸執行的順序是自上而下再從下向上返回
因為是多組測試數據,所以需要在遞歸返回時,把迷宮“恢復原貌”
#include<iostream> using namespace std; #define min(a,b) a < b ? a : b int Map[9][9] = {1,1,1,1,1,1,1,1,1, 1,0,0,1,0,0,1,0,1, 1,0,0,1,1,0,0,0,1, 1,0,1,0,1,1,0,1,1, 1,0,0,0,0,1,0,0,1, 1,1,0,1,0,1,0,0,1, 1,1,0,1,0,1,0,0,1, 1,1,0,1,0,0,0,0,1, 1,1,1,1,1,1,1,1,1,}; int a,b,c,d,num; void dfs(int x,int y,int s){ if(Map[x][y]) return; if(x == c && y == d){ num = min(s,num); return; } s++; Map[x][y] = 1; dfs(x - 1,y,s); dfs(x + 1,y,s); dfs(x,y - 1,s); dfs(x,y + 1,s); Map[x][y] = 0; } int main(){ int n; cin >> n; while(n--){ num = 10000; cin >> a >> b >> c >> d; dfs(a,b,0); cout << num << endl; } return 0; }
DFS,BFS講解PPT:click here || there