机试算法讲解: 第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
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 搓背搓的脖子红痒怎么办 上班迟到1个小时怎么办 想家想的都哭怎么办 想学手艺被骗学费怎么办 小腿肚后面筋和肌肉压痛怎么办 尿道囗和屁股眼中间长疮怎么办? 2个多月的宝宝蛋蛋上有个包怎么办 幼儿园睡觉自己摸下身玩怎么办 猫猫打喷嚏有透明液体怎么办 夏季穿运动鞋出了脚气怎么办 脚底长了刺瘊子怎么办 凉鞋前面踢破了怎么办 尖头鞋前面折了怎么办 月子里宝宝蛋蛋破皮怎么办 军人在训练时想上侧所怎么办 被白蚂蚁咬了怎么办 被蚂蚁咬了起包怎么办 脚踢了石头肿了怎么办 脚大拇指踢肿了怎么办 被骨头咯到了疼怎么办 被开水烫着了疼怎么办 鞋子上踩了口香糖怎么办 鞋底踩到口香糖干了怎么办 鞋子不小心踩到口香糖怎么办 站久了膝盖痛怎么办 站久了脚底板痛怎么办 蛇疮好了以后痛怎么办 站久了脚趾痛怎么办 心脏被踢了一脚怎么办 从马背上摔下来怎么办 小孩蛋蛋碰撞后有积液怎么办 小孩蛋蛋大小不一样有积液怎么办 对派出所的笔录不服怎么办 蛋蛋让尿淹了发红有小红瘩达怎么办 手被皮筋弹肿了怎么办 手被皮筋勒肿了怎么办 皮筋把手挤肿了怎么办 猫被皮筋绑久肿了怎么办 抗链0高关节疼怎么办 近视800度老了怎么办 军检体重不达标怎么办