【原创】
今天来说说深度优先搜索,深度优先是图论中的内容,大意是从某一点出发,沿着一个方向搜索下去,并伴随着有回退的特点,通常用来判断某一解是否存在,不用来寻找最优解;这里来看一个非常有意思的题目;
题目描述:一只小狗在迷宫中,假设在迷宫用字符表示,如图所示:
S.X. ..X. ...D
这其中,S表示起点,是需要程序寻找出来的,这里比较特殊,在最左上角,“.”表示可走的格子,D表示出口,X表示强,不能走,每一秒小狗必须移动一个距离,即前后左右,那么输入时间t,小狗能否刚好在t秒的时间上到达D,看清楚是刚好在t秒上,不是至少在t秒内,所以程序中的判断应该注意这一点,
思想:利用深度优先搜索,将每一个点的状态抽象出来,一个三元组(x,y,t);x,y代表坐标,t表示从起点到这一坐标的时间,那么这就是一个状态,深度搜索的任务就是对状态的扩展,观察并判断是否到达目标状态;见如下代码,注释地方都有,同时支持多组测试数据;
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 //深度优先搜索 5 //小狗逃离迷宫问题 6 char maze[8][8];//输入的迷宫规模1 < n < 7 7 int nd,md,t;//nd和md表示是矩阵迷宫的规模,t为时间,nd表示x方向,md表示y方向 8 bool success;//标记 9 int go[][2] = {1,0,-1,0,0,1,0,-1};//一个点可以扩展的上下左右四个状态 10 void DFS(int x,int y,int time){ 11 for (int i = 0; i<4; i++) {//对这个点进行四个方向的扩展 12 int nx = x+go[i][0]; 13 int ny = y+go[i][1]; 14 if (nx<1||nx>nd||ny<1||ny>md) continue;//表示跳出了迷宫 15 if(maze[nx][ny]=='X')continue;//该位置为墙 16 if(maze[nx][ny]=='D'){//找到了出口, 17 if(time+1==t){//由于题目要求的是t时间刚好到达出口,所以这里不能用<t作为判断; 18 success = true; 19 return; 20 } 21 else 22 continue;//继续,并且该状态的后继状态不可能为答案, 23 } 24 maze[nx][ny] = 'X';//说明这个状态能够扩展,之所以将其修改为墙,是因为防止后继状态又扩展回这个状态 25 DFS(nx, ny, time+1);// 继续从该状态扩展 26 maze[nx][ny] = '.';//返回后要将其修改回原来的状态 27 if(success)return;//说明找到了目标状态且满足题意,可以返回; 28 } 29 } 30 void test_3(){ 31 while (scanf("%d%d%d",&nd,&md,&t)!=EOF) { 32 if (nd==0&&md==0&&t==0) break; 33 for (int i = 1; i<=nd;i++) { 34 scanf("%s",maze[i]+1);//输入字符迷宫,必须+1,这才是从[1][1]开始的 35 } 36 success = false; 37 for (int i = 1;i<=nd;i++) {//寻找开始坐标 38 for (int j = 1; j<=md; j++) { 39 if(maze[i][j]=='S'){ 40 maze[i][j] = 'X';//将起点标记为墙 41 DFS(i,j,0);//开始扩展; 42 break; 43 } 44 } 45 } 46 puts(success==true?"YES":"NO"); 47 48 } 49 } 50 int main() { 51 // test_1(); 52 // test_2(); 53 test_3(); 54 return 0; 55 } 56 57 /************************************************************** 58 Problem: 1461 59 User: Numen_fan 60 Language: C++ 61 Result: Accepted 62 Time:10 ms 63 Memory:1020 kb 64 ****************************************************************/
注:迷宫输入一定是从maze[1][1],开始的,因此34行处scanf("%s",maze[i]+1);还有就是24-16行代码处应该好好理解一下,注释有提出