这段时间做了很多很耗时的题目,想总结一下,学到了什么。。。
首先第一道是风水吧,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 ", result-2 ); // 老虎和老狼相遇啦哈哈哈 200 else 201 printf( "-1 " ); 202 // -1, 太遗憾了,居然木有相遇,真的哭的心都有了TAT 203 } 204 return 0; 205 }
八维数组忒长了一点,代码格式都乱了*.* 。。。