深度優先搜索
基本思想:先選擇一種可能情況向前探索,在探索過程中,一點那發現原來的選擇是錯誤的,就退回一步重新選擇,繼續向前探索,(回溯)反復進行。
【例題】迷宮問題 ——【傳送門】
思路:先隨意選擇一個方向,一步步向前試探,如果碰到死胡同說明該前進方向已經無路可走,這時首先看別的方向還是否有路可走,若有路可走,則該方向再次向前試探,若沒有,則退回上一步,再看其他方向是否有路可走,,按此原則不斷回溯和探索,知道找到入口為止。
框架:
int search(int ......) { for(i=1;i<=方向總數;i++) if(滿足條件) { 保存結果; if(到達目的地) 輸出解; else search(k+1); 恢復:保存結果之前的狀態{回溯一步}; } }
具體代碼實現如下:
#include<iostream> #include<cstdio> #include<cstring>
#define MAXN 20
using namespace std; int map[MAXN][MAXN];//表示迷宮地圖
bool temp[MAXN][MAXN];//標記是否走過
int dx[4]={0,0,1,-1};//橫坐標的上下左右
int dy[4]={-1,1,0,0};//縱坐標的上下左右
int m,n,total,sx,sy,fx,fy,l,r,t;//m,n:地圖的長寬,total:方案總數,sx,sy起點的橫縱坐標,fx,fy:終點的橫縱坐標,t:障礙總數,l,r:障礙坐標
void search(int x,int y)//x,y:現在所在的點的坐標
{ if(x==fx&&y==fy)//到達終點
{ total++;//方案總數
return; //返回繼續尋找
} for(int i=0;i<=3;i++) if(temp[x+dx[i]][y+dy[i]]==0&&map[x+dx[i]][y+dy[i]]==1)//判斷下面要走的路是否有障礙
if(x+dx[i]>=1&&y+dy[i]>=1&&x+dx[i]<=n&&y+dy[i]<=m)//判斷是否超越迷宮邊界
{ temp[x+dx[i]][y+dy[i]]=1; search(x+dx[i],y+dy[i]); temp[x+dx[i]][y+dy[i]]=0;//回溯一步
} } int main() { cin>>n>>m>>t; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) map[i][j]=1; cin>>sx>>sy; cin>>fx>>fy; for(int i=1;i<=t;i++) { cin>>l>>r; map[l][r]=0; } map[sx][sy]=0; search(sx,sy); printf("%d",total); return 0; }