初看这道题时,给我的第一影响是DFS,我很happy的敲了一下代码,发现了各种问题,我还是像往常一样设置map数组存放地图,visit标记数组,dir方向数组,等我测试几组数据后发现,这样设置visit数组是不行的,因为我们不知道哪个地方会出现加时器 ,而我们采用的是深度优先搜索,会使很多路径无法走 参考了大牛的博客后,我发现他巧妙地将visit数组的功效用了不同的含义 还设置了时间数组。
下面讲下我的理解:到底什么时候用DFS还是BFS更好,一般如果某一层次下没有优先权的区别,或者说元素优先权对最终的最优解没有影响,此时DFS、BFS都是可以的,反之BFS更好。到底DFS中什么时候应该用到回溯,我的理解就是“如果最终要求的结果不涉及最优解的话(也就是说只要有解就行,不要求最好;或者所有的解都是一样的,没有最优性的区别的时候,比如说让你统计某迷宫下的字符的个数或者块什么的)”,那么是不需要回溯的,反之一般就要考虑回溯的思想了。
杭电1072这道题:让我知道了,visit数组失去常义标记作用的时候,我们应该怎么处理应付。
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1072
还真是不做不知道,即日不敲搜索题,又有点生疏了,唉...我这脑袋长得,同学们,有时间就刷题吧,别荒废了。
个人觉得BFS比DFS要简单点,只要懂队列的一些简单操作的话,根据DFS的思路,相信聪明的你定能敲出来,我就不敲了^_^
下面我的AC代码:
深搜(DFS):
#include <iostream> using namespace std; #define INF 0xfffffff #define M 10 int n,m,Min; int step[M][M],tim[M][M]; //step[i][j]表示从起点到i、j位置需要的最小步数,time[i][j]表示走到i、j位置还剩下的时间 char maze[M][M]; int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}}; void dfs(int x,int y) { if(tim[x][y]<=0) //没时间了 return ; if(maze[x][y]=='3') { if (step[x][y]<Min) //找到最小值 Min=step[x][y]; return ; } for(int i=0;i<4;i++) { int a=x+dir[i][0]; int b=y+dir[i][1]; if(a<0||a>=n||b<0||b>=m) continue; if(maze[a][b]=='0'||step[a][b]<=step[x][y]+1&&tim[a][b]>=tim[x][y]-1) continue; //已访问过,而且如果走下去诈弹时间没变甚至变小,那还不如不走呢 step[a][b]=step[x][y]+1; tim[a][b]=tim[x][y]-1; if(maze[a][b]=='4'&&tim[a][b]>0) tim[a][b]=6; dfs(a,b); } } int main() { int t,i,j,sx,sy; scanf("%d",&t); while(t--) { scanf ("%d%d",&n,&m); getchar(); memset(maze,0,sizeof(maze)); for(i=0;i<n;i++) { for(j=0;j<m;j++) { scanf("%c",&maze[i][j]); if(maze[i][j]=='2') sx=i,sy=j; step[i][j]=INF; //初始化步数为无穷大 getchar(); } } step[sx][sy]=0; //到起点的最小步数是0 memset(tim,0,sizeof(tim)); tim[sx][sy]=6; Min=INF; dfs(sx,sy); if(Min==INF) //如果没有任何路径逃生的话,那么Min是不会变的 puts("-1"); else printf("%d\n",Min); } return 0; }
写的不好的地方,还望理解...因为我是小白^_^