poj3083 Children of the Candy Corn dfs 和 bfs 的综合,终于AC了

2014-03-13

TLE后就把输入和输出全改成 scanf( ) 和 printf( ) 了,但还是超时。感觉是搜索最短路径时用的方法太慢了。下面是TLE的代码:

  1 ///2014.3.11 - 2014.3.13
  2 ///poj3083
  3 
  4 #include <iostream>
  5 #include <cstdio>
  6 using namespace std;
  7 
  8 int w,h;               ///记录迷宫的大小
  9 char maze[50][50];     ///记录迷宫
 10 int start_w,start_h;   ///记录迷宫的开始位置
 11 int start_pre;         ///其前一步的相对于现在位置的方向,
 12                             ///0表示在右,1表示在上面,2表示在左边,3是下面
 13 bool findmin;          ///标记有没有找到最短路
 14 int step;
 15 
 16 int next_w[4] = {1,0,-1,0};   ///方便走下一步
 17 int next_h[4] = {0,-1,0,1};
 18 
 19 void dfs(int h,int w,int pre,int l_r)
 20 {
 21     step++;
 22     if( maze[h][w]=='E' ){
 23         return;
 24     }
 25     if( maze[h+next_h[(pre+l_r)%4] ][w+next_w[(pre+l_r)%4] ] !='#' ){
 26         dfs( h+next_h[(pre+l_r)%4], w+next_w[(pre+l_r)%4], (pre+l_r+2)%4,l_r);
 27     }
 28     else if( maze[h+next_h[(pre+l_r*2)%4] ][w+next_w[(pre+l_r*2)%4] ] !='#' ){
 29         dfs( h+next_h[(pre+l_r*2)%4], w+next_w[(pre+l_r*2)%4], (pre+l_r*2+2)%4,l_r);
 30     }
 31     else if( maze[h+next_h[(pre+l_r*3)%4] ][w+next_w[(pre+l_r*3)%4] ] !='#' ){
 32         dfs( h+next_h[(pre+l_r*3)%4], w+next_w[(pre+l_r*3)%4], (pre+l_r*3+2)%4,l_r);
 33     }
 34     else{
 35         dfs( h+next_h[pre], w+next_w[pre], (pre+2)%4,l_r);
 36     }
 37 }
 38 
 39 void bfs(int h,int w,int pre,int deep)
 40 {
 41     step++;
 42 
 43     if( findmin ) return;
 44     if( maze[h][w]=='E' ){
 45         findmin = true;
 46         return;
 47     }
 48     if( deep==step ){
 49         return;
 50     }
 51 
 52     if( maze[h+next_h[(pre+1)%4] ][w+next_w[(pre+1)%4] ] !='#' ){
 53         bfs( h+next_h[(pre+1)%4], w+next_w[(pre+1)%4], (pre+1+2)%4,deep);
 54         step--;
 55     }
 56     if( maze[h+next_h[(pre+2)%4] ][w+next_w[(pre+2)%4] ] !='#' ){
 57         bfs( h+next_h[(pre+2)%4], w+next_w[(pre+2)%4], (pre+2+2)%4,deep);
 58         step--;
 59     }
 60     if( maze[h+next_h[(pre+3)%4] ][w+next_w[(pre+3)%4] ] !='#' ){
 61         bfs( h+next_h[(pre+3)%4], w+next_w[(pre+3)%4], (pre+3+2)%4,deep);
 62         step--;
 63     }
 64 }
 65 
 66 void init()
 67 {
 68     char c;
 69     scanf("%d%d",&w,&h);
 70     scanf("%c",&c);
 71     for(int i=1 ; i<=h ; i++){
 72         for(int j=1 ; j<=w ; j++){
 73             scanf("%c",&c);
 74             maze[i][j] = c;
 75             if( c=='S' ){
 76                 start_w = j;
 77                 start_h = i;
 78                 if( j==1 )
 79                     start_pre = 2;
 80                 else if( j==w )
 81                     start_pre = 0;
 82                 else if( i==1 )
 83                     start_pre = 1;
 84                 else
 85                     start_pre = 3;
 86             }
 87         }
 88         scanf("%c",&c);
 89     }
 90     step = 0;
 91 }
 92 
 93 int main()
 94 {
 95 //    freopen("in","r",stdin);
 96 //    freopen("out","w",stdout);
 97 
 98     int cas;
 99     scanf("%d",&cas);
100     while( cas-- ){
101         init();
102 
103         dfs(start_h,start_w,start_pre,3);
104         printf("%d ",step);
105 
106         step = 0;
107         dfs(start_h,start_w,start_pre,1);
108         printf("%d ",step);
109 
110         findmin = false;
111         int deep;
112         for(deep=1 ; !findmin ; deep++){
113             step = 0;
114             bfs(start_h,start_w,start_pre,deep);
115         }
116         printf("%d\n",--deep);
117     }
118     return 0;
119 }

 2014-03-17

  这个题折磨了我好几天,知道自己的bfs方法太慢,但是自己太菜了,不知道怎么改。各种不甘心,所以上英语课时找出CSDN上那个很厉害的“小优学姐”的代码研究。(http://blog.csdn.net/lyy289065406/article/details/6647668

  得到启发思路,从新写代码A掉这一题,废话少说,上代码:

  1 ///2014.3.17
  2 ///poj3083
  3 
  4 #include <iostream>
  5 #include <cstdio>
  6 #include <cstring>
  7 using namespace std;
  8 
  9 int W,H;               ///记录迷宫的大小
 10 char maze[50][50];     ///记录迷宫
 11 int start_w,start_h;   ///记录迷宫的开始位置
 12 int start_pre;         ///其前一步的相对于现在位置的方向,
 13                             ///0表示在右,1表示在上面,2表示在左边,3是下面
 14 int step;
 15 
 16 int next_w[4] = {1,0,-1,0};   ///方便走下一步
 17 int next_h[4] = {0,-1,0,1};
 18 
 19 void dfs(int h,int w,int pre,int l_r)  ///l_r变量决定优先左拐还是右拐
 20 {
 21     step = 1; ///起点是第一步
 22     while( maze[h][w] != 'E' ){
 23         step++;
 24         if( maze[h+next_h[(pre+l_r)%4] ][w+next_w[(pre+l_r)%4] ] !='#' ){
 25             h = h+next_h[(pre+l_r)%4];
 26             w = w+next_w[(pre+l_r)%4];
 27             pre = (pre+l_r+2)%4;
 28         }
 29         else if( maze[h+next_h[(pre+l_r*2)%4] ][w+next_w[(pre+l_r*2)%4] ] !='#' ){
 30             h = h+next_h[(pre+l_r*2)%4];
 31             w = w+next_w[(pre+l_r*2)%4];
 32             pre = (pre+l_r*2+2)%4;
 33         }
 34         else if( maze[h+next_h[(pre+l_r*3)%4] ][w+next_w[(pre+l_r*3)%4] ] !='#' ){
 35             h = h+next_h[(pre+l_r*3)%4];
 36             w = w+next_w[(pre+l_r*3)%4];
 37             pre = (pre+l_r*3+2)%4;
 38         }
 39         else{
 40             h = h+next_h[pre];
 41             w = w+next_w[pre];
 42             pre = (pre+2)%4;
 43         }
 44     }
 45     printf("%d ",step);
 46 }
 47 
 48 void bfs(int h,int w)  ///建立一个搜索树,'E'的深度就是最少的步数
 49 {
 50     int p,q;
 51     p=q=0;
 52     
 53     int h_queue[1650];     ///记录搜到的每一步的h坐标
 54     int w_queue[1650];     ///记录搜到的每一步的w坐标
 55     int deep_queue[1650];  ///记录搜到的每一步的深度
 56 
 57     bool visited[50][50];
 58     memset(visited,false,sizeof(bool)*50*50);
 59     
 60     h_queue[1] = h;
 61     w_queue[1] = w;
 62     deep_queue[1] = 1;
 63     p=0;
 64     q=1;
 65 
 66     while( p!=q ){
 67         p++;
 68         if( maze[ h_queue[p] ][ w_queue[p]+1 ]=='.' 
 69             && !visited[ h_queue[p] ][ w_queue[p]+1 ] 
 70             || maze[ h_queue[p] ][ w_queue[p]+1 ]=='E'){
 71             if(maze[ h_queue[p] ][ w_queue[p]+1 ]=='E'){
 72                 printf("%d\n",deep_queue[p]+1 );
 73                 break;
 74             }
 75             q++;
 76             visited[ h_queue[p] ][ w_queue[p]+1 ] = true;
 77             h_queue[q] = h_queue[p];
 78             w_queue[q] = w_queue[p]+1;
 79             deep_queue[q] = deep_queue[p]+1;
 80         }
 81         if( maze[ h_queue[p]+1 ][ w_queue[p] ]=='.' 
 82             && !visited[ h_queue[p]+1 ][ w_queue[p] ] 
 83             || maze[ h_queue[p]+1 ][ w_queue[p] ]=='E'){
 84             if(maze[ h_queue[p]+1 ][ w_queue[p] ]=='E'){
 85                 printf("%d\n",deep_queue[p]+1 );
 86                 break;
 87             }
 88             q++;
 89             visited[ h_queue[p]+1 ][ w_queue[p] ] = true;
 90             h_queue[q] = h_queue[p]+1;
 91             w_queue[q] = w_queue[p];
 92             deep_queue[q] = deep_queue[p]+1;
 93         }
 94         if( maze[ h_queue[p] ][ w_queue[p]-1 ]=='.' 
 95             && !visited[ h_queue[p] ][ w_queue[p]-1 ] 
 96             || maze[ h_queue[p] ][ w_queue[p]-1 ]=='E'){
 97             if(maze[ h_queue[p] ][ w_queue[p]-1 ]=='E'){
 98                 printf("%d\n",deep_queue[p]+1 );
 99                 break;
100             }
101             q++;
102             visited[ h_queue[p] ][ w_queue[p]-1 ] = true;
103             h_queue[q] = h_queue[p];
104             w_queue[q] = w_queue[p]-1;
105             deep_queue[q] = deep_queue[p]+1;
106         }
107         if( maze[ h_queue[p]-1 ][ w_queue[p] ]=='.' 
108             && !visited[ h_queue[p]-1 ][ w_queue[p] ] 
109             || maze[ h_queue[p]-1 ][ w_queue[p] ]=='E'){
110             if(maze[ h_queue[p]-1 ][ w_queue[p] ]=='E'){
111                 printf("%d\n",deep_queue[p]+1 );
112                 break;
113             }
114             q++;
115             visited[ h_queue[p]-1 ][ w_queue[p] ] = true;
116             h_queue[q] = h_queue[p]-1;
117             w_queue[q] = w_queue[p];
118             deep_queue[q] = deep_queue[p]+1;
119         }
120     }
121 }
122 
123 void init()
124 {
125     char c;
126     scanf("%d%d",&W,&H);
127     scanf("%c",&c);
128     for(int i=1 ; i<=H ; i++){    ///读入迷宫
129         for(int j=1 ; j<=W ; j++){
130             scanf("%c",&c);
131             maze[i][j] = c;
132             if( c=='S' ){      ///找到起点并设置起点信息
133                 start_w = j;
134                 start_h = i;
135                 if( j==1 )
136                     start_pre = 2;
137                 else if( j==H )
138                     start_pre = 0;
139                 else if( i==1 )
140                     start_pre = 1;
141                 else
142                     start_pre = 3;
143             }
144         }
145         scanf("%c",&c);
146     }
147     step = 0;
148 }
149 
150 int main()
151 {
152     // freopen("in","r",stdin);
153     // freopen("out","w",stdout);
154 
155     int cas;
156     scanf("%d",&cas);
157     while( cas-- ){
158         init();  ///初始化工作
159         dfs(start_h,start_w,start_pre,3); ///优先左拐
160         dfs(start_h,start_w,start_pre,1); ///优先右拐
161         bfs(start_h,start_w);  ///最短步数
162     }
163     return 0;
164 }

  递归效率太低了,这次深刻体会~

posted @ 2014-03-13 19:53  basement_boy  阅读(177)  评论(0编辑  收藏  举报