机试算法讲解: 第46题 深度优先搜索之能否逃出魔掌
来源:互联网 发布:淘宝助理上传宝贝 编辑:程序博客网 时间:2024/05/18 00:41
/*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 5S.X...X...XD....3 4 5S.X...X....D0 0 0输出:NOYES关键: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 7using 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//如果一直遍历不到,则返回-1return;}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;}
0 0
- 机试算法讲解: 第46题 深度优先搜索之能否逃出魔掌
- 机试算法讲解: 第44题 深度优先搜索之素数环问题
- 机试算法讲解: 第45题 深度优先搜索之寻找沙特石油存储区
- 机试算法讲解: 第41题 广度优先搜索之迷宫问题
- 机试算法讲解: 第42题 广度优先搜索之我该如何倒可乐
- 图深度优先搜索之能否到达终点
- 算法之深度优先搜索和广度优先搜索
- 经典算法之深度优先搜索
- 图算法二之深度优先搜索
- 深度优先搜索:能否走出迷宫
- 深度优先搜索算法
- 深度优先搜索算法
- 深度优先搜索算法
- 深度优先搜索算法
- 深度优先搜索算法
- 【深度优先搜索算法】
- 深度优先搜索算法
- 深度优先搜索算法
- PF_INET 和 AF_INET的区别
- 机试算法讲解: 第45题 深度优先搜索之寻找沙特石油存储区
- onvif学习2-soap介绍以及gsoap使用
- 数据同步相关专利
- svn的配置和使用
- 机试算法讲解: 第46题 深度优先搜索之能否逃出魔掌
- Linux socket编程(三) 简单的多线程聊天室
- Servlet之login
- hdu 2037
- 深入理解Hadoop集群和网络
- Foj 1075 分解素因子
- 面向对象_封装
- 机试算法讲解:第47题 递推之N阶楼梯如何上楼
- TCP/IP学习笔记(一) .