• 风水风水风风水水水水风风


    SZU Problem(B40):Fengshui

    这道题超级坑,就是一个大大的坑,后台有三组数据,总题目的时间不能超过3秒,但是每组数组不能超过1秒,否则case time limited. 

    因为我的方法很简单,就是套用BFS,八个方向为一个状态。。。不知道为什么,三组数据的总时间不超3秒,但她老人家第一数据就老超一秒,然后我就一直一直一直过不了。。

    后来优化到已经不能再优化了,我就突然发现,我的queue的数组好像开得有点点大,这样每轮初始化花的时间也会增加,我就只给了他几乎刚刚的量,然后就AC啦~~

    啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊阿啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊超开心^^

    Judge Info

    • Memory Limit: 32768KB
    • Case Time Limit: 15000MS
    • Time Limit: 30000MS
    • Judger: Normal

    Description

    Fengshui is an ancient subject in Chinese tradition. Someone considers it as science and someone criticizes it as blind faith. Who knows! However, in modern days, everyone should respect culture from our ancestor!

    Fengshui focus on geography,environment and staffs' position, all the theory come from a very old book named "YI". YI means change. Everything is always changing in the world. Fengshui wishes to guide changing, make life change to a better situation. Now let's look at Fengshui's changing.

    At first we must know about the traditional five elements system which composed by GOLD,WOOD,GROUND,WATER and FIRE. Everything in the world can be represented by one and only one element. For example, river is represented by WATER, hill is represented by GROUND. Here, we only consider the elements. In this system, once element can kill another element, and one element can born anther element. Five elements compose as a circuit, as in Figure 1.

    Every place has eight direction - east, west, north, south, northeast, northwest, southeast and southwest. Every direction has a represented element. Now, our problem is about the elements at these eight directions which form a Fengshui situation. Figure 2 is an example of one Fengshui situation.

    • But Fengshui situation can change! There're two change ways:
      • TURN: The whole situation turn clockwise one step. Figure 3 shows the situation that situation in Figure 2 makes one TURN change.
      • REBORN: Based on kill and born relation, one direction's element can be killed by another direction's (at any other place) element in the situation, and then the killed element will born out as the new element at its direction. Of course, kill and born are all according as the relation of the system as in Figure 1. In situation of Figure 3, WATER in east can kill FIRE in southeast, then southeast place change to be GROUND, as in Figure 4.

    Each change, no matter TURN or REBORN, const one step.

    Now, there're two Fengshui situation, we want to know is it possible that first one can change to the second one? And if possible, how many steps it need at least?

    Input

    There're several cases, the first line of input is the number of cases. Every case includes 6 lines, the first 3 lines indeicate the first Fengshui situation, the last 3 lines incicate the second Fengshui situation.

    The format of one situation is as follow, there may be arbitrary blanks between adjacent directions.

    northwest  north  northeast
    west                   east
    southwest  south  southeast
    

    Output

    For every case, output the number of the least changing steps on a single line, if it is possible, or output -1.

    Sample Input

    2
    GOLD WOOD WATER
    WATER     FIRE
    WOOD GOLD GROUND
    WATER GOLD WOOD
    WOOD       WATER
    GOLD GROUND GROUND
    WATER GROUND WOOD
    GOLD         FIRE
    GOLD  FIRE   GROUND
    GOLD  FIRE   FIRE
    GOLD         FIRE
    WATER GROUND WOOD
    

    Sample Output

    2 
    14

    虽然代码很长很罗嗦,而且跑得很慢,刚刚卡三秒的时间,但我还是很开心啊哈哈哈哈哈哈~
      1 #include <stdio.h>
      2 #include <string.h>
      3 #define L 5
      4 #define N 8
      5 #define M 3125050
      6 int former[N];
      7 int goal[N];
      8 int sign[L];
      9 int kill[] = { 3, 0, 4, 2, 1 };
     10 int born[] = { 2, 3, 1, 4, 0 };
     11 int distance[L][L][L][L][L][L][L][L];
     12 int flag[L][L][L][L][L][L][L][L];
     13 int queue[M];
     14 int sequence[] = { 0, 1, 2, 7, 3, 6, 5, 4 };
     15  
     16 int main()
     17 {
     18     char temp[N];
     19     int t, i, j, k, p, head;
     20     scanf( "%d", &t );
     21     while( t-- )
     22     {
     23         // 初始化
     24         memset( distance, 0, sizeof(distance) );
     25         memset( flag, 0, sizeof(flag) );
     26         p = 0;
     27         for( i=0; i<N; ++i )
     28         {
     29             scanf( "%s", temp );
     30             if( temp[0] == 'G' && temp[1] == 'O' )
     31                 former[sequence[p++]] = 0;
     32             else if( temp[0] == 'W' && temp[1] == 'O' )
     33                 former[sequence[p++]] = 1;
     34             else if( temp[0] == 'W' && temp[1] == 'A' )
     35                 former[sequence[p++]] = 2;
     36             else if( temp[0] == 'F' && temp[1] == 'I' )
     37                 former[sequence[p++]] = 3;
     38             else
     39                 former[sequence[p++]] = 4;
     40         }
     41         p = 0;
     42         for( i=0; i<N; ++i )
     43         {
     44             scanf( "%s", temp );
     45             if( temp[0] == 'G' && temp[1] == 'O' )
     46                 goal[sequence[p++]] = 0;
     47             else if( temp[0] == 'W' && temp[1] == 'O' )
     48                 goal[sequence[p++]] = 1;
     49             else if( temp[0] == 'W' && temp[1] == 'A' )
     50                 goal[sequence[p++]] = 2;
     51             else if( temp[0] == 'F' && temp[1] == 'I' )
     52                 goal[sequence[p++]] = 3;
     53             else
     54                 goal[sequence[p++]] = 4;
     55         }
     56         head = p = 0;
     57         for( i=0; i<N; ++i )
     58             queue[p++] = former[i];
     59         flag[former[0]][former[1]][former[2]][former[3]][former[4]][former[5]][former[6]][former[7]] = 1;
     60         while( head < p )
     61         {
     62             memset( sign, 0, sizeof(sign) );
     63             for( i=0; i<N; ++i )
     64             {
     65                 former[i] = queue[head+i];
     66                 sign[former[i]] = 1;
     67             }
     68  
     69             int x = distance[former[0]][former[1]][former[2]][former[3]][former[4]][former[5]][former[6]][former[7]];
     70  
     71  
     72             // 顺时针旋转
     73             int temp = former[N-1];
     74             for( i=N-1; i>0; --i )
     75                 former[i] = former[i-1];
     76  
     77             former[0] = temp;
     78  
     79             if( flag[former[0]][former[1]][former[2]][former[3]][former[4]][former[5]][former[6]][former[7]] == 0 )
     80             {
     81                 distance[former[0]][former[1]][former[2]][former[3]][former[4]][former[5]][former[6]][former[7]] = x+1;
     82                 flag[former[0]][former[1]][former[2]][former[3]][former[4]][former[5]][former[6]][former[7]] = 1;
     83  
     84                 for( i=0; i<N; ++i )
     85                     if( former[i] != goal[i] )
     86                         break;
     87                 if( i == N  ) // 一致跳出while循环
     88                     break;
     89                 else // 不一致放入队列中去
     90                     for( i=0; i<N; i++ )
     91                         queue[p++] = former[i];
     92             }
     93             // 相克替换
     94  
     95             for( k=0; k<N; k++ ) // for一遍
     96             {
     97                 if( sign[kill[queue[head+k]]] == 1 ) // 如果相克
     98                 {
     99                             // 从队列中得到当前状态
    100                     for( j=0; j<N; ++j )
    101                         former[j] = queue[head+j];
    102                     former[k] = born[queue[head+k]]; // 进行替换
    103                     if( flag[former[0]][former[1]][former[2]][former[3]][former[4]][former[5]][former[6]][former[7]] == 0 )
    104                     {
    105                         distance[former[0]][former[1]][former[2]][former[3]][former[4]][former[5]][former[6]][former[7]] = x+1;
    106                         flag[former[0]][former[1]][former[2]][former[3]][former[4]][former[5]][former[6]][former[7]] = 1;
    107  
    108                         for( j=0; j<N; ++j )
    109                             if( former[j] != goal[j] )
    110                                 break;
    111                         if( j == N )
    112                             goto END;
    113                         else
    114                             for( j=0; j<N; ++j )
    115                                 queue[p++] = former[j];
    116                     }
    117                 }
    118             }
    119             head += 8;
    120         }
    121 END:    if( head < p )
    122             printf( "%d
    ", distance[former[0]][former[1]][former[2]][former[3]][former[4]][former[5]][former[6]][former[7]] );
    123         else
    124             printf( "-1
    " );
    125     }
    126     return 0;
    127 }
  • 相关阅读:
    FJSC2020合集
    考试前注意事项
    CSP-S&&NOIP2020游记
    IOI2020集训队作业题单
    对拍程序
    Re:memset 赋值
    2019-12-29 Div.3模拟赛题解
    NOI2020 游记
    边三连通分量算法
    【题解】Code+7 教科书般的亵渎
  • 原文地址:https://www.cnblogs.com/zhongshuxin/p/3280577.html
Copyright © 2020-2023  润新知