dfs解決全排列問題
典型題目:用數字 1~5進行全排列,顯示出每一種情況並計算出總共有多少種情況。
#include <iostream>
using namespace std;
const int n = 5;
int ans = 0;
int a[n+1];
int book[n] = {0}; //0 表示還沒用
void bfs(int step)
{
if (step==n+1) // **邊界條件
{
ans++; //統計情況總數
for (int j=1;j<=n;j++) //顯示每種可能
cout<<a[j]<<" ";
cout<<endl;
return; // 返回上一步 (這裏的返回很重要)
}
for (int i=1;i<=n;i++) //**遍歷所有可能的數字
{
if (book[i]==0) //**判斷情況是否已經處理過
{
a[step] = i; //**嘗試這個數字
book[i] = 1; //**把數字標記爲【已嘗試】
bfs(step+1); //**遞歸下一個位
book[i] = 0; //**嘗試結束,取消標記
}
}
return; //返回
}
int main()
{
bfs(1); //如果參數是 1,則邊界條件爲 n+1;如果是 0,邊界則是 n
cout<<ans<<endl;
return 0;
}
dfs解決迷宮問題
題目:給出迷宮大小、迷宮簡圖、起點座標,終點座標。求到達終點的路徑數和最短路徑所需的步數。
#include <iostream>
using namespace std;
int maze[10][10];
int book[10][10] = {0}; // 標記該座標是否走過
int dx[4] = {1,0,-1,0}; //方向
int dy[4] = {0,1,0,-1};
int ans = 0; //到達終點的路線數目
int minn = 99999; // 最小步數
int m,n; // 迷宮大小
int sx,sy; //起點
int gx,gy; // 終點
void dfs(int x,int y,int step)
{
if (x==gx && y==gy) // **邊界條件
{
ans++;
if (step < minn) minn = step;
return; //返回上一步 (這裏的返回很重要)
}
for (int k=0;k<4;k++) // **遍歷所有情況(枚舉 4 個方向的走法
{
int nx = x + dx[k];
int ny = y + dy[k];
// **判斷當前情況是否可用
if (0<=nx && nx<m && 0<=ny && ny<n) //判斷是否有越界
{
if (book[nx][ny] == 0 && maze[nx][ny] == 0) // 判斷是否已經走過或者是否是障礙
{
book[nx][ny] = 1; //**標記這個點已經用過(走過)
dfs(nx,ny,step+1); //**遞歸
book[nx][ny] = 0; //**嘗試結束,取消這個點的標記
}
}
}
return;
}
int main()
{
int i,j;
cin>>m>>n; // 迷宮的行,列
cin>>sx>>sy>>gx>>gy; //輸入起點座標和終點座標
for (i=0;i<m;i++)
for (j=0;j<n;j++)
cin>>maze[i][j];
book[0][0] = 1; // (0,0)爲起點,默認爲已經走過
dfs(sx,sy,0); //
cout<<"路線數目: "<<ans<<endl;
cout<<"最短路徑: "<<minn<<endl;
return 0;
}
dfs大致的模版:
void dfs(int step)
{
if (...) 邊界條件
{
...
return; //返回上一步(這裏一定要寫)
}
for (i=0;i<n;i++) 嘗試每一種可能
{
if (...) 判斷當前可能是否可用
{
...
book[i] = 1; //標記這個可能已經嘗試
dfs(step+1); //繼續下一步
book[i] = 0; //嘗試結束,取消該點的標記(這裏一定要寫)
}
}
return;
}