POJ_3083_Children of the Candy Corn(BFS+DFS)

/*

http://poj.org/problem?id=3083

 

  看完题目之后自己心中便已有思路,因为前面做过几道这类搜索的题目了,但是自己真写起来的时候却

不知所措,只好看了 会网上的代码然后再自己写出来。虽然是看别人的但是着实从里面学了不少东西,

我想以后在遇着这种题目已经会个八九成了。

题意:

这道题的意思就是让你找走出迷宫的路径。分为左优先和右优先还有最短路径,输出的也是这三种路径的步数。

思路:1:对于最短路径肯定想到的是用广搜,因为广搜是一层一层的搜,适合这种找最小路径的问题。光搜实现的时候使用的是队列

两个位置变量,一个在首部,一个在尾部。尾部是入队操作,首部是访问操作,直到找到最短路径。队列元素可以使结构体类型,最重要的是保存

树的深度,可以这样理解,因为他是一层一层的访问,如果访问的是同一层他的深度是不加一的。因此队列元素保存的是走到当前位置(或者是在这一层时树的深度)。

这也是广度搜索与深度搜索的区别。

2:对于左优先和右优先的步数,使用的是深度优先搜索,类似于二叉树的前序遍历。即如果一直满足条件就一直搜下去,直到不满足条件后退一步再一直搜下去。

在这道题中,需要注意的是它访问过的点还有可能返回再访问,因此不能使用标记。处理方法就是使用一个方向变量d,d记录的是当前朝哪个方向走,

当三个方向都不满足时,那么只能往回走,此时前方便是往回走的方向,因此保证了他不会第二次回头。

3:还是那句话,对于每个函数,一定要想清楚这个函数的功能是什么。像这里的DFS他就是找左优先的步数,传过去的是起始点意思是说找从这个点

到结束点的步数,函数里面又出现了递归调用(到下一个位置的步数加一即为当前)。

*/

  1 # include <stdio.h>
  2 # include <string.h>
  3 struct node 
  4 {
  5     int r;
  6     int c;
  7     int depth;
  8 };
  9 struct node q,p;
 10 int map[50][50];
 11 int visit[50][50];
 12 int leftstep;
 13 int rightstep;
 14 int shortstep;
 15 void DFS_left(int i,int j,int d)
 16 {
 17     leftstep++;
 18     if(i==q.r && j==q.c )
 19         return ;
 20     switch (d)
 21     {
 22         case 0: 
 23             {
 24                 if(map[i][j-1])
 25                     DFS_left(i,j-1,1);
 26                 else if(map[i-1][j])
 27                     DFS_left(i-1,j,0);
 28                 else if(map[i][j+1])
 29                     DFS_left(i,j+1,3);
 30                 else
 31                     DFS_left(i+1,j,2);
 32                 break;
 33             }
 34         case 1:
 35             {
 36                 if(map[i+1][j])
 37                     DFS_left(i+1,j,2);
 38                 else if(map[i][j-1])
 39                     DFS_left(i,j-1,1);
 40                 else if(map[i-1][j])
 41                     DFS_left(i-1,j,0);
 42                 else
 43                     DFS_left(i,j+1,3);
 44                 break;
 45             }
 46         case 2:
 47             {
 48                 if(map[i][j+1])
 49                     DFS_left(i,j+1,3);
 50                 else if(map[i+1][j])
 51                     DFS_left(i+1,j,2);
 52                 else if(map[i][j-1])
 53                     DFS_left(i,j-1,1);
 54                 else
 55                     DFS_left(i-1,j,0);
 56                 break;
 57             }
 58         case 3:
 59             {
 60                 if(map[i-1][j])
 61                     DFS_left(i-1,j,0);
 62                 else if(map[i][j+1])
 63                     DFS_left(i,j+1,3);
 64                 else if(map[i+1][j])
 65                     DFS_left(i+1,j,2);
 66                 else
 67                     DFS_left(i,j-1,1);
 68                 break;
 69             }
 70 
 71     }
 72     return ;
 73 }
 74 void DFS_right(int i,int j,int d)
 75 {
 76     rightstep++;
 77     if(i==q.r && j==q.c )
 78         return ;
 79     switch (d)
 80     {
 81         case 0: 
 82         {
 83             if(map[i][j+1])
 84                  DFS_right(i,j+1,3);
 85             else if(map[i-1][j])
 86                 DFS_right(i-1,j,0);
 87             else if(map[i][j-1])
 88                 DFS_right(i,j-1,1);
 89             else
 90                 DFS_right(i+1,j,2);
 91             break;
 92         }
 93         case 1:    
 94         {
 95             if(map[i-1][j])
 96                 DFS_right(i-1,j,0);
 97             else if(map[i][j-1])
 98                 DFS_right(i,j-1,1);
 99             else if(map[i+1][j])
100                 DFS_right(i+1,j,2);
101             else
102                 DFS_right(i,j+1,3);
103             break;
104         }
105     case 2:    
106         {
107             if(map[i][j-1])
108                 DFS_right(i,j-1,1);
109             else if(map[i+1][j])
110                 DFS_right(i+1,j,2);
111             else if(map[i][j+1])
112                 DFS_right(i,j+1,3);
113             else
114                 DFS_right(i-1,j,0);
115             break;
116         }
117     case 3:    
118         {
119             if(map[i+1][j])
120                 DFS_right(i+1,j,2);
121             else if(map[i][j+1])
122                 DFS_right(i,j+1,3);
123             else if(map[i-1][j])
124                 DFS_right(i-1,j,0);
125             else
126                 DFS_right(i,j-1,1);
127             break;
128         }
129         
130     }
131     return ;
132 }
133 void BFS_short(int i,int j)
134 {
135     struct node x,dq[2000]; //dq为队列,临时记录待广搜的点。
136     int head=0,tail=0; //Initial;
137     dq[head].r=i;
138     dq[head].c=j;
139     dq[tail++].depth=1;
140     visit[i][j]=true;   //
141     while(head<tail)
142     {
143         x=dq[head++];
144         if(x.r==q.r  && x.c==q.c)  //找到终点结束
145         {
146             printf("%d\n",x.depth);
147             return ;
148         }
149         if(map[x.r][x.c-1] && !visit[x.r][x.c-1]) //广搜顺序可调换;如果他们都满足情况都得入队列。
150         {
151             visit[x.r][x.c-1]=1;
152             dq[tail].r=x.r;
153             dq[tail].c=x.c-1;
154             dq[tail++].depth=x.depth+1;  //广搜深度加1;注意并不是队列加一个元素深度就加1;
155                                         //如果在同一层的元素深度不加1;x代表的是上一层。            
156         }
157         if(map[x.r-1][x.c] && !visit[x.r-1][x.c])
158         {
159             visit[x.r-1][x.c]=1;
160             dq[tail].r=x.r-1;
161             dq[tail].c=x.c;
162             dq[tail++].depth=x.depth+1;
163         }
164         if(map[x.r][x.c+1] && !visit[x.r][x.c+1])
165         {
166             visit[x.r][x.c+1]=1;
167             dq[tail].r=x.r;
168             dq[tail].c=x.c+1;
169             dq[tail++].depth=x.depth+1;
170         }
171         if(map[x.r+1][x.c] && !visit[x.r+1][x.c])  
172         {  
173                   visit[x.r+1][x.c]=true;  
174                   dq[tail].r=x.r+1;  
175                   dq[tail].c=x.c;  
176                   dq[tail++].depth=x.depth+1;  
177         } 
178         
179     }
180     return ;
181 
182 }
183 int main()
184 {
185     int test,i,j,k,m,n,d;
186     char ch[50][50];
187     scanf("%d",&test);
188     while(test--)
189     {
190         scanf("%d%d",&m,&n);
191         getchar();
192         for(i=0;i<n;i++)
193             scanf("%s",ch[i]);
194         memset(map,0,sizeof(map));    //地图
195         memset(visit,0,sizeof(visit));//visit初始化都没被访问过
196         for(i=0;i<n;i++)
197         {
198             for(j=0;j<m;j++)
199             {
200                 if(ch[i][j] == '.')
201                     map[i+1][j+1]=1;
202                 else if(ch[i][j]=='S')
203                 {
204                     map[i+1][j+1]=1;
205                     visit[i+1][j+1]=1;
206                     p.r=i+1; //记录起点
207                     p.c=j+1;
208                     if(i+1==n) //记录第一步走的方向。
209                         d=0; //朝上
210                     else if(i+1==1)
211                         d=2; //朝下
212                     else if(j+1==m)
213                         d=1; //朝左
214                     else if(j+1==1)
215                         d=3; //朝右
216                 }
217                 else if(ch[i][j]=='E')
218                 {
219                     map[i+1][j+1]=1;
220                     q.r=i+1; //记录终点;
221                     q.c=j+1;
222                 }
223             }
224         }
225 
226         //left_step;
227         leftstep=1;
228         switch(d)
229         {
230             case 0: {DFS_left(p.r-1,p.c,0);break;}//0朝上,上走一步行减1;
231             case 1: {DFS_left(p.r,p.c-1,1);break;}//1朝左,左走一步列减1;
232             case 2: {DFS_left(p.r+1,p.c,2);break;}//2朝上
233             case 3: {DFS_left(p.r,p.c+1,3);break;}//3朝右
234         }
235         printf("%d ",leftstep);
236 
237         //right_step;
238         rightstep=1;
239         switch(d)
240         {
241             case 0: {DFS_right(p.r-1,p.c,0);break;}
242             case 1: {DFS_right(p.r,p.c-1,1);break;}
243             case 2: {DFS_right(p.r+1,p.c,2);break;}
244             case 3: {DFS_right(p.r,p.c+1,3);break;}
245         }
246         printf("%d ",rightstep);
247 
248         //shorted_step;
249         shortstep=0;
250         BFS_short(p.r,p.c); //起点为p开始广搜;
251     }
252     return 0;
253 }

 

 

posted on 2013-08-14 10:46  随风浪子的博客  阅读(125)  评论(0编辑  收藏  举报

导航