GDCPC 2008:F Fengshui

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, one element can kill another element, and one element can born another element. Five elements compose as a circuit, as in Figure 2.6.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.6.2 is an example of one Fengshui situation. 

 

But Fengshui situation can change! There’re two change ways:

1. TURN: The whole situation turn clockwise one step. Figure 2.6.3 shows the situation that situation in Figure 2.6.2 makes one TURN change. 

2. 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 2.6.1. In situation of Figure 2.6.3, WATER in east can kill FIRE in southeast, then southeast place change to be GROUND, as in Figure 2.6.4. 

 

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

Now, there’re two Fengshui situations, we want to know is it possible that first one can change to the second one? And if possible, how many steps it needs 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 indicate 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. Output -1 on a single line in case of no solution.

 

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.该图顺时针旋转

2.如果某个元素在途中存在克制它的元素,那么这个元素可以被杀并生成新的元素

问通过几步能达到目标图

 

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
using namespace std;

int pos[8] = {0,1,2,7,3,6,5,4};//8个位置
int ppow[8] = {78125,15625,3125,625,125,25,5,1};//5的幂表
int start,end,vis[1000000],mark[5];
char s[10];

int solve(char s[])//五行对应的状态
{
    if(!strcmp(s,"GOLD")) return 0;
    if(!strcmp(s,"WOOD")) return 1;
    if(!strcmp(s,"GROUND")) return 2;
    if(!strcmp(s,"WATER")) return 3;
    if(!strcmp(s,"FIRE")) return 4;
    return -1;
}

int BFS()
{
    int a,step,i;
    int g[8];
    queue<int> Q;
    Q.push(start);
    while(!Q.empty())
    {
        int k;
        a = Q.front();
        Q.pop();
        if(a == end)
            return vis[end];
        k = a%5*ppow[0]+a/5;//第一种方法,顺时针,将a/5,每个位置的基值都是5的幂,所以可以看成每个位置都顺时针移了一格,而第一个位置的则必定小于5得到了0,在通过对a取余可以将第一个位置的移动到末尾
        if(!vis[k])
        {
            Q.push(k);
            vis[k] = vis[a]+1;//步数
        }
        memset(mark,0,sizeof(mark));//标记那些元素是存在的
        k = a;
        for(i = 7; i>=0; i--)
        {
            g[i] = k%5;
            k/=5;
            mark[g[i]] = 1;
        }
        for(i = 0; i<8; i++)//第二种方法
        {
            if(mark[(g[i]+4)%5])//存在克制的元素,则相克相生
            {
                k = a-g[i]*ppow[i]+((g[i]+3)%5)*ppow[i];
                if(!vis[k])
                {
                    Q.push(k);
                    vis[k] = vis[a]+1;
                }
            }
        }
    }
    return -1;
}

int main()
{
    int t,i,j;
    scanf("%d",&t);
    while(t--)
    {
        start = end = 0;
        for(i = 0; i<8; i++)//将状态改为数字
        {
            scanf("%s",s);
            start+=ppow[pos[i]]*solve(s);
        }
        for(i = 0; i<8; i++)
        {
            scanf("%s",s);
            end+=ppow[pos[i]]*solve(s);
        }
        memset(vis,0,sizeof(vis));
        printf("%d\n",BFS());
    }

    return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值