/* DFS:主要用于求解有或者没有的问题,用栈。而BFS:用于求解最优问题,用队列。 问题:有一个N*M的迷宫,起点S,终点D,墙X和地面,'.'表示路,0秒时,我从S出发,每秒能走到4个与其相邻位置的任意一个,行走之后不能再次走入。问:是否存在一条路径使主人公刚好在 T秒走到D 确定状态:(x,y,t),x与y是当前点坐标,t为从起点走到该点所需要的时间。 剪枝依据:起点坐标和的奇偶性和终点坐标的不同,但是经过偶数秒到达,不可能 输入:第一行3个整数,N(1<n,M<7,共有N行),M(M列),T(时间,0<T<50)。下面是N行,每行有M个字符, 输入: 4 4 5 S.X. ..X. ..XD .... 3 4 5 S.X. ..X. ...D 0 0 0 输出: NO YES 关键: 1 这里用深度优先搜索,就不需要用栈了,因为已经用了递归. 2 广度优先搜索需要使用访问标记,mark[][].而深度优先搜索由于要退回到上一层,因此不需要设置访问标记,而只需要设置成功标记 3 深度优先搜索的固定格式:maze[][] = 'X';DFS();maze[][]='.',递归前设置状态为不可用,递归后设置状态为可用,用于下一次退回使用 4 设置初始节点,要将起始状态设为墙,在进行深度搜索。这里没有使用标记mark的原因是'X'墙,'.'路已经起到了标记的作用,并且深度优先搜索设置已访问标记没有效果, 向上回溯的时候,标记还需要设为可用 5 需要验证起始节点和结束节点以及时间之间的正确性,如果校验正确才进行递归,if((statBegin.x + statBegin.y)%2==((statEnd.x + statEnd.y)%2 + t%2)%2) */ #include <stdio.h> #include <string.h> #include <stdlib.h> #include <stack> #define N 7 using namespace std; typedef struct Stat { int x,y;//横纵坐标 int t;//耗费时间 }Stat; //stack<Stat> stackStat;//保存状态的堆栈 //bool mark[N][N];//剪枝标记 char maze[N][N];//保存迷宫元素 bool success;//设置是否找到的成功标记 //走下一个位置的数组 int goNext[][2] = {0,1, -1,0, 1,0, 0,-1 }; //深度优先搜索 void DFS(int x,int y,int t,int n,int m,int tLimit) { int i ; for(i = 0 ; i < 4 ; i ++) { int iXNext = x + goNext[i][0]; int iYNext = y + goNext[i][1]; //判定有无超过迷宫位置 if(iXNext < 1 || iXNext > n || iYNext < 1 || iYNext > m) { continue; } //判定是否是墙 if('X'==maze[iXNext][iYNext]) { continue; } //判定是否到达终点,并且时间要符合 if('D'==maze[iXNext][iYNext] && tLimit==(t + 1)) { //易错,需要设置成功标记 success = true; return; } maze[iXNext][iYNext] = 'X'; //递归调用 DFS(iXNext,iYNext,t+1,n,m,tLimit); //若其后续状态全部遍历完毕,返回上层状态,因为要搜索后续状态,因此再将墙改为普通状态 maze[iXNext][iYNext] = '.'; //易错,判断是否搜索成功 if(true==success) { return; } }//for //如果一直遍历不到,则返回-1 return; } int main(int argc,char* argv[]) { int n,m,t; int i,j; while(EOF!=scanf("%d %d %d",&n,&m,&t)) { if(0==n && 0==m && 0==t) { break; } //获取输入信息,按行接受输入 for(i = 1; i <= n;i++) { scanf("%s",maze[i]+1);//输入中不能用\n } //将起始点和结束点挑选出来 Stat statBegin,statEnd; for(i = 1 ; i <= n ; i++) { for(j = 1 ; j <= m ; j++) { //如果找到起始点 if('S'==maze[i][j]) { statBegin.x = i; statBegin.y = j; } //如果找到结束点 if('D'==maze[i][j]) { statEnd.x = i; statEnd.y = j; } } } success = false; //如果校验正确才进行递归 if((statBegin.x + statBegin.y)%2==((statEnd.x + statEnd.y)%2 + t%2)%2) { maze[statBegin.x][statBegin.y] = 'X'; DFS(statBegin.x,statBegin.y,0,n,m,t); } puts(success==true ? "YES":"NO"); } system("pause"); getchar(); return 0; }