深度优先搜索
基本思想:先选择一种可能情况向前探索,在探索过程中,一点那发现原来的选择是错误的,就退回一步重新选择,继续向前探索,(回溯)反复进行。
【例题】迷宫问题 ——【传送门】
思路:先随意选择一个方向,一步步向前试探,如果碰到死胡同说明该前进方向已经无路可走,这时首先看别的方向还是否有路可走,若有路可走,则该方向再次向前试探,若没有,则退回上一步,再看其他方向是否有路可走,,按此原则不断回溯和探索,知道找到入口为止。
框架:
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;
}