• 小小小小小总结(风水双向BFS)


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

    首先第一道是风水吧,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 }

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

  • 相关阅读:
    linux学习之路(2)
    Cocos.js
    BOM常用对象
    display取值和应用
    DOM
    cursor属性
    visibilty属性
    打开新连接的方式
    JQuery
    js的创建对象
  • 原文地址:https://www.cnblogs.com/zhongshuxin/p/3288583.html
Copyright © 2020-2023  润新知