Fengshui(双向bfs看风水···)

来源:互联网 发布:淘宝僵尸号买东西 编辑:程序博客网 时间:2024/06/06 01:47

先记录一个当时一时兴起想出来的歌谣:

风水算得好 小神有三宝

一宝曰广搜 阴阳五行 相生相克 探清形煞安福

二宝曰八维 八方八维 无穷幻变 洞察世事万千

三宝曰双向 由始向终 由终寻始 方得安居乐业


哈哈,这里提到了本题需要的几个关键词,广度搜索bfs,八维数组,双向bfs


Judge Info


  • Memory Limit: 32768KB
  • Case Time Limit: 10000MS
  • 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  northeastwest                   eastsouthwest  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

2GOLD WOOD WATERWATER     FIREWOOD GOLD GROUNDWATER GOLD WOODWOOD       WATERGOLD GROUND GROUNDWATER GROUND WOODGOLD         FIREGOLD  FIRE   GROUNDGOLD  FIRE   FIREGOLD         FIREWATER GROUND WOOD


Sample Output

2 14


题意就是输入两组八个方向的五行,然后通过两组规则“转向”和“再生”进行变换,看看第一组风水图最少需要几次变换才能变成第二组图,不行就-1

这里我们先用map库里的map把五行映射成数字,方便我们计算

接下来对其进行九个方向的广搜,内容为转向和八种再生,介于本题的时间要求,我们必须使用双向bfs。即对起点进行正向搜索,对结尾进行反向搜索直到他们接触到彼此。不过要小心触碰时的细节,还有队列要开大点不然很容易溢出。记得用八维的bool数组记录变化情况。

#include<iostream>#include<map>#include<string>#include<memory.h>using namespace std;char v[5][5][5][5][5][5][5][5];int s[8],e[8]; bool issame(int *a,int *b)//判断两个序列是否相同{bool flag=1;for(int i=0;i<8;i++)if(a[i]!=b[i]){flag=0;break;}return flag;} void Turn(int *a,int *b)//顺时针转向{b[0]=a[7];for(int i=1;i<8;i++)b[i]=a[i-1];} void reTurn(int *a,int *b)//逆时针转向{b[7]=a[0];for(int i=0;i<7;i++)b[i]=a[i+1];} bool canReborn(int *a,int n)//能否再生{bool flag=0;for(int i=0;i<8;i++)if(a[i]==(a[n]+4)%5){flag=1;break;}return flag;} bool canBorn(int *a,int n)//能否反向再生{bool flag=0;for(int i=0;i<8;i++)if(a[i]==(a[n]+1)%5){flag=1;break;}return flag;} void Reborn(int *a,int n,int *b)//再生{for(int i=0;i<8;i++)b[i]=a[i];b[n]=(a[n]+3)%5;} void Born(int *a,int n,int *b)//反向再生{for(int i=0;i<8;i++)b[i]=a[i];b[n]=(a[n]+2)%5;} struct line{int fengshui[400000][9];//每个点存储八个数字和一个步数int *p;int *q;line(){p=fengshui[0];q=fengshui[0];}void push(int t,int* a){for(int i=0;i<8;i++)q[i]=a[i];q[8]=t;q+=9;}void pop(){p+=9;}int *ask(){return p;}bool isnull(){if(p==q)return true;elsereturn false;}void initialize(){p=fengshui[0];q=fengshui[0];} }; line sl,el;//正反两个序列 int main(){map<string,int> wuxing;//简单的map映射wuxing["GOLD"]=0;wuxing["WOOD"]=1;wuxing["GROUND"]=2;wuxing["WATER"]=3;wuxing["FIRE"]=4;int n;cin>>n;while(n--){string wx;for(int i=0;i<3;i++){cin>>wx;s[i]=wuxing[wx];}cin>>wx;s[7]=wuxing[wx];cin>>wx;s[3]=wuxing[wx];for(int i=6;i>3;i--){cin>>wx;s[i]=wuxing[wx];}for(int i=0;i<3;i++){cin>>wx;e[i]=wuxing[wx];}cin>>wx;e[7]=wuxing[wx];cin>>wx;e[3]=wuxing[wx];for(int i=6;i>3;i--){cin>>wx;e[i]=wuxing[wx];}//由于用户输入不是顺时针的,所以次序有点乱sl.initialize();el.initialize();int t1=0,t2=0;sl.push(0,s);el.push(0,e);int flag=0; int fs[8];int xl[8];int *p;if(issame(s,e)){cout<<0<<endl;continue;}else{memset(v,0,390625*sizeof(char));v[s[0]][s[1]][s[2]][s[3]][s[4]][s[5]][s[6]][s[7]]=1;v[e[0]][e[1]][e[2]][e[3]][e[4]][e[5]][e[6]][e[7]]=2;}while(!flag){while(!flag&&!sl.isnull()&&(p=sl.ask())[8]==t1){sl.pop();for(int i=0;i<8;i++)fs[i]=p[i];Turn(fs,xl);if(v[xl[0]][xl[1]][xl[2]][xl[3]][xl[4]][xl[5]][xl[6]][xl[7]]!=1){v[xl[0]][xl[1]][xl[2]][xl[3]][xl[4]][xl[5]][xl[6]][xl[7]]++;if(v[xl[0]][xl[1]][xl[2]][xl[3]][xl[4]][xl[5]][xl[6]][xl[7]]==3){flag=1;break;}sl.push(t1+1,xl);}for(int i=0;!flag&&i<8;i++){if(canReborn(fs,i)){Reborn(fs,i,xl);if(v[xl[0]][xl[1]][xl[2]][xl[3]][xl[4]][xl[5]][xl[6]][xl[7]]!=1){v[xl[0]][xl[1]][xl[2]][xl[3]][xl[4]][xl[5]][xl[6]][xl[7]]++;if(v[xl[0]][xl[1]][xl[2]][xl[3]][xl[4]][xl[5]][xl[6]][xl[7]]==3){flag=1;break;}sl.push(t1+1,xl);}}}}if(flag!=1){if(sl.isnull()) flag=2;}while(!flag&&!el.isnull()&&(p=el.ask())[8]==t2){el.pop();for(int i=0;i<8;i++)fs[i]=p[i];reTurn(fs,xl);if(v[xl[0]][xl[1]][xl[2]][xl[3]][xl[4]][xl[5]][xl[6]][xl[7]]!=2){v[xl[0]][xl[1]][xl[2]][xl[3]][xl[4]][xl[5]][xl[6]][xl[7]]+=2;if(v[xl[0]][xl[1]][xl[2]][xl[3]][xl[4]][xl[5]][xl[6]][xl[7]]==3){flag=3;break;}el.push(t2+1,xl);}for(int i=0;!flag&&i<8;i++){if(canBorn(fs,i)){Born(fs,i,xl);if(v[xl[0]][xl[1]][xl[2]][xl[3]][xl[4]][xl[5]][xl[6]][xl[7]]!=2){v[xl[0]][xl[1]][xl[2]][xl[3]][xl[4]][xl[5]][xl[6]][xl[7]]+=2;if(v[xl[0]][xl[1]][xl[2]][xl[3]][xl[4]][xl[5]][xl[6]][xl[7]]==3){flag=3;break;}el.push(t2+1,xl);}}}}if(flag==0){if(el.isnull()) flag=2;else{t1++;t2++;}}}if(flag==1) cout<<t1+t2+1<<endl;else if(flag==3) cout <<t1+t2+2<<endl;else cout<<-1<<endl;}return 0;}


广搜的细节很多,反正现在看到广搜真心有种想吐的感觉。。。





0 0
原创粉丝点击