这段时间做了很多很耗时的题目,想总结一下,学到了什么。。。

首先第一道是风水吧,BFS的。

我觉得,这道题,首先要想清楚,用怎么表示状态,方法有很多吧,但我能想到的,很暴力,八个方向,就开了一个八维的数组,嘻嘻,OJ老大,对不起啦哈哈哈~

这道题可以用单向和双向的BFS,如果用单向的BFS和跟我一样想挑战OJ极限的孩子们,注意啦,数组开得要刚刚好,真的是算好那种开,你稍稍开大一丢丢,OJ就会报你超时 - - 我只能给你们点一支蜡烛了^.^....看我之前发过的代码,其实,是有个地方可以优化的,其实没有必要开标记数组,每一次初始化这个东西,真的忒耗时,你想啊,一个点只能更新一次,当它被更新的时候,他一定是distance[][][][][][][][] == 0 时,他才能被更新,这不是可以用作一个标记吗?对不对对不对。。。

昨天下午开始,请教了一下小叶姐姐,双向BFS的思路,就想试着敲一下。。

双向BFS, 就是起点和终点同时走,直到两个东西相遇,就跳出来,输出两个距离之和。。就类似于两个BFS,我就copy了一下,从昨晚调到刚刚,真的哭的心都有了TT...

刚刚开始,我是开了4个八维的数组,两个计算步数,两个用来标记,跑了4000+MS,flag这两数组去掉了,2000+MS,快超多,标记数组的初始化超耗时!!!记得最后结果要-2~

  1 /*******************前有狼,后有虎*****************************/
  2 /************狼虎何时相遇,双向BFS为你诠释*********************/
  3 #include <stdio.h>
  4 #include <string.h>
  5 #define L 5
  6 #define N 8
  7 #define M 3125050
  8 int former[N];
  9 int goal[N];
 10 int sign[L]; // 狼和老虎有标记
 11 int kill[] = { 3, 0, 4, 2, 1 }; // 被克
 12 int born1[] = { 2, 3, 1, 4, 0 }; // 狼是生
 13 int born2[] = { 4, 2, 0, 1, 3 }; // 老虎的五行是被生
 14 int distance1[L][L][L][L][L][L][L][L]; //  计算狼的步长
 15 int distance2[L][L][L][L][L][L][L][L]; // 计算老虎的步长
 16 int queue1[M]; // 狼的队列
 17 int queue2[M]; // 老虎的队列
 18 int sequence[] = { 0, 1, 2, 7, 3, 6, 5, 4 };
 19 
 20 int main()
 21 {
 22     char str[N];
 23     int t, i, j, k, fl, fr, gl, gr, p, x, temp, result = -1;
 24     scanf( "%d", &t );
 25     while( t-- )
 26     {
 27         // 初始化
 28         memset( distance1, 0, sizeof(distance1) );
 29         memset( distance2, 0, sizeof(distance2) );
 30         result = -1;
 31         p = 0;
 32         for( i=0; i<N; ++i )
 33         {
 34             scanf( "%s", str );
 35             if( str[0] == 'G' && str[1] == 'O' )
 36                 former[sequence[p++]] = 0;
 37             else if( str[0] == 'W' && str[1] == 'O' )
 38                 former[sequence[p++]] = 1;
 39             else if( str[0] == 'W' && str[1] == 'A' )
 40                 former[sequence[p++]] = 2;
 41             else if( str[0] == 'F' && str[1] == 'I' )
 42                 former[sequence[p++]] = 3;
 43             else
 44                 former[sequence[p++]] = 4;
 45         }
 46         p = 0;
 47         for( i=0; i<N; ++i )
 48         {
 49             scanf( "%s", str );
 50             if( str[0] == 'G' && str[1] == 'O' )
 51                 goal[sequence[p++]] = 0;
 52             else if( str[0] == 'W' && str[1] == 'O' )
 53                 goal[sequence[p++]] = 1;
 54             else if( str[0] == 'W' && str[1] == 'A' )
 55                 goal[sequence[p++]] = 2;
 56             else if( str[0] == 'F' && str[1] == 'I' )
 57                 goal[sequence[p++]] = 3;
 58             else
 59                 goal[sequence[p++]] = 4;
 60         }
 61 
 62         fl = fr = gl = gr = 0; // fl,  fr, gl, gr两对指针,fl, fr是狼,gl, gr是老虎^^ 两者相遇,必有一场恶战,哈哈哈我是坏女人^^
 63         for( i=0; i<N; ++i )
 64         {
 65             queue1[fr++] = former[i];
 66             queue2[gr++] = goal[i];
 67         }
 68         distance1[former[0]][former[1]][former[2]][former[3]][former[4]][former[5]][former[6]][former[7]] = 1;  // 老狼到此一游!!
 69         distance2[goal[0]][goal[1]][goal[2]][goal[3]][goal[4]][goal[5]][goal[6]][goal[7]] = 1; // 老虎也到此一游啦!!!
 70         while( 1 )
 71         {
 72             if( fl >= fr || gl >= gr )
 73                 break;
 74 
 75              if( fr-fl <= gr-gl )
 76             {
 77                 p = 0;
 78                 while( fl < fr )
 79                 {
 80                     memset( sign, 0, sizeof(sign) );
 81                     for( i=0; i<N; ++i )
 82                     {
 83                         former[i] = queue1[fl+i];
 84                         sign[former[i]] = 1;
 85                     }
 86 
 87                     x = distance1[former[0]][former[1]][former[2]][former[3]][former[4]][former[5]][former[6]][former[7]]; // 猜猜老狼走了多少步?
 88                     // 老狼在顺时针旋转
 89                     temp = former[N-1];
 90                     for( i=N-1; i>0; --i )
 91                         former[i] = former[i-1];
 92                      former[0] = temp;
 93 
 94                     if( distance1[former[0]][former[1]][former[2]][former[3]][former[4]][former[5]][former[6]][former[7]] == 0 ) // 表示该点的步数没有被更新过
 95                     {
 96                         distance1[former[0]][former[1]][former[2]][former[3]][former[4]][former[5]][former[6]][former[7]] = x+1;
 97 
 98                         if( distance2[former[0]][former[1]][former[2]][former[3]][former[4]][former[5]][former[6]][former[7]] != 0 )
 99                         {
100                             result = distance1[former[0]][former[1]][former[2]][former[3]][former[4]][former[5]][former[6]][former[7]]+distance2[former[0]][former[1]][former[2]][former[3]][former[4]][former[5]][former[6]][former[7]];
101                             goto END;
102                         }
103                         else
104                             for( i=0; i<N; i++ )
105                                 queue1[fr+(p++)] = former[i];
106                     }
107 
108                     // 相克替换
109                     for( k=0; k<N; k++ ) // for一遍
110                     {
111                         if( sign[kill[queue1[fl+k]]] == 1 ) // 如果狼克的五行存在
112                         {
113                             // 从队列中得到当前状态
114                             for( j=0; j<N; ++j )
115                                 former[j] = queue1[fl+j];
116                             former[k] = born1[queue1[fl+k]]; // 用生的进行替换
117                             if( distance1[former[0]][former[1]][former[2]][former[3]][former[4]][former[5]][former[6]][former[7]] == 0 ) // 狼没有来过,到此一游^^
118                             {
119                                 distance1[former[0]][former[1]][former[2]][former[3]][former[4]][former[5]][former[6]][former[7]] = x+1;
120 
121                                  if( distance2[former[0]][former[1]][former[2]][former[3]][former[4]][former[5]][former[6]][former[7]] != 0 )
122                                 {
123                                     result = distance1[former[0]][former[1]][former[2]][former[3]][former[4]][former[5]][former[6]][former[7]]+distance2[former[0]][former[1]][former[2]][former[3]][former[4]][former[5]][former[6]][former[7]];
124                                     goto END;
125                                 }
126                                 else
127                                        for( i=0; i<N; i++ )
128                                         queue1[fr+(p++)] = former[i];
129                             }
130                         }
131                     }
132                     fl += 8;
133                 }
134                 fr += p;
135             }
136             else
137             {
138                 p = 0;
139                 while( gl < gr )
140                 {
141                     memset( sign, 0, sizeof(sign) );
142                     for( i=0; i<N; ++i )
143                     {
144                         goal[i] = queue2[gl+i];
145                         sign[goal[i]] = 1;
146                     }
147                     x = distance2[goal[0]][goal[1]][goal[2]][goal[3]][goal[4]][goal[5]][goal[6]][goal[7]]; // 那老虎呢?他们还有多久才能相遇TT
148                     // 老虎忒淘气,喜欢跟老狼反着干,偏偏逆时针
149                      temp = goal[0];
150                      for( i=0; i<N-1; i++ )
151                          goal[i] = goal[i+1];
152                      goal[N-1] = temp;
153 
154                     if( distance2[goal[0]][goal[1]][goal[2]][goal[3]][goal[4]][goal[5]][goal[6]][goal[7]] == 0 ) // 老虎还没有来过呢~
155                     {
156                         distance2[goal[0]][goal[1]][goal[2]][goal[3]][goal[4]][goal[5]][goal[6]][goal[7]] = x+1;
157 
158                         if( distance1[goal[0]][goal[1]][goal[2]][goal[3]][goal[4]][goal[5]][goal[6]][goal[7]] != 0 )
159                         {
160                             result = distance1[goal[0]][goal[1]][goal[2]][goal[3]][goal[4]][goal[5]][goal[6]][goal[7]]+distance2[goal[0]][goal[1]][goal[2]][goal[3]][goal[4]][goal[5]][goal[6]][goal[7]];
161                             goto END;
162                         }
163                         else
164                             for( i=0; i<N; i++ )
165                                 queue2[gr+(p++)] = goal[i];
166                     }
167 
168                     // 相克替换
169 
170                     for( k=0; k<N; k++ ) // for一遍
171                     {
172                         if( sign[kill[born2[queue2[gl+k]]]] == 1 ) // 如果能生成老虎五行的存在
173                         {
174                             // 从队列中得到当前状态
175                             for( j=0; j<N; ++j )
176                                 goal[j] = queue2[gl+j];
177                             goal[k] = born2[queue2[gl+k]]; // 用能生的东西替代就好啦
178                                 if( distance2[goal[0]][goal[1]][goal[2]][goal[3]][goal[4]][goal[5]][goal[6]][goal[7]] == 0 ) // 老虎来啦哈哈哈啊哈
179                             {
180                                 distance2[goal[0]][goal[1]][goal[2]][goal[3]][goal[4]][goal[5]][goal[6]][goal[7]] = x+1;
181 
182                                 if( distance1[goal[0]][goal[1]][goal[2]][goal[3]][goal[4]][goal[5]][goal[6]][goal[7]] != 0 )
183                                 {
184                                     result = distance1[goal[0]][goal[1]][goal[2]][goal[3]][goal[4]][goal[5]][goal[6]][goal[7]]+distance2[goal[0]][goal[1]][goal[2]][goal[3]][goal[4]][goal[5]][goal[6]][goal[7]];
185                                     goto END;
186                                 }
187                                 else
188                                     for( i=0; i<N; i++ )
189                                         queue2[gr+(p++)] = goal[i];
190                             }
191                         }
192                     }
193                     gl += 8;
194                 }
195                 gr += p;
196             }
197         }
198 END:    if( result != -1 )      
199             printf( "%d\n", result-2 );  // 老虎和老狼相遇啦哈哈哈
200         else
201             printf( "-1\n" );
202             // -1, 太遗憾了,居然木有相遇,真的哭的心都有了TAT
203     }
204     return 0;
205 }

八维数组忒长了一点,代码格式都乱了*.* 。。。

posted on 2013-08-29 10:41  钟SX  阅读(310)  评论(0编辑  收藏  举报