二阶魔方

    博客开通第一天,写个随笔纪念一下:

    今天介绍二阶魔方的求解方法:

     问题很简单,给二阶魔方的任意状态,求解一个二阶魔方还原的方法,如下为还原后的情况:

        
         很显然把魔方上每个位置先标个号:

        

         然后建立个旋转关系很简单!

         旋转操作包括:前方顺时针,前方逆时针,上方顺时,上逆时,右顺时,右逆时;

         (不用左、下、后是因为相对性)。

         输入:按1~24填颜色。(这里还是按 hdu3459 的输入方式)

         . . WO . . . .
         . . WO . . . .
         BBOYGGWR
         BBOYGGWR
         . . YR . . . .
         . . Y R . . . .
      输出:一种转法。

         X Y Z 分别为按X、Y、Z轴顺时旋转的一步操作。

   

       具体只要按部双向宽搜,还是很容易的,注意 写好类与具体操作的函数就很好办了。

       本人考证过,二阶总状态数在百万级,所以双向宽搜效果已经很好了!非常快非常快!!

       之所以可以双向因为在后面左下方的那个角在我们的操作中是不变的,所以根据它可以推出各个面的终态颜色。当然,每个人有自己的写法,一下是我写的,比较繁琐也很臃肿= =,以后会努力写的精炼!

       #include <iostream>
#include <cstdio>
#include <map>
#include <queue>
using namespace std;

int F[24]={9,10,12,11,3,13,22,8,4,15,21,6};
int U[24]={1,2,4,3,18,14,10,6,17,13,9,5};
int R[24]={13,14,16,15,2,19,22,10,4,17,24,12};


struct node
{
char s[26];
bool from;
__int64 change()
{
__int64 x=0;
for(int i=1;i<25;i++)
{
x=x*6+s[i];
}
return x;
}
void change(__int64 x)
{
for(int i=24;i>0;i--)
{
s[i]=x%6;
x/=6;
}
}
};




struct state
{
__int64 pre;
int how;bool from;
};



node Fcloroude(node po)
{
int tmp;
for(int i=0;i<12;i+=4)
{
tmp=po.s[F[i+3]];
for(int j=3;j>0;j--)
{
po.s[F[j+i]]=po.s[F[i+j-1]];
}
po.s[F[i]]=tmp;
}
return po;
}
node Ucloroude(node po)
{
int tmp;
for(int i=0;i<12;i+=4)
{
tmp=po.s[U[i+3]];
for(int j=3;j>0;j--)
{
po.s[U[j+i]]=po.s[U[i+j-1]];
}
po.s[U[i]]=tmp;
}
return po;
}
node Rcloroude(node po)
{
int tmp;
for(int i=0;i<12;i+=4)
{
tmp=po.s[R[i+3]];
for(int j=3;j>0;j--)
{
po.s[R[j+i]]=po.s[R[i+j-1]];
}
po.s[R[i]]=tmp;
}
return po;
}
node Funcloroude(node po)
{
int tmp;
for(int i=0;i<12;i+=4)
{
tmp=po.s[F[i]];
for(int j=0;j<3;j++)
{
po.s[F[j+i]]=po.s[F[i+j+1]];
}
po.s[F[i+3]]=tmp;
}
return po;
}
node Uuncloroude(node po)
{
int tmp;
for(int i=0;i<12;i+=4)
{
tmp=po.s[U[i]];
for(int j=0;j<3;j++)
{
po.s[U[j+i]]=po.s[U[i+j+1]];
}
po.s[U[i+3]]=tmp;
}
return po;
}
node Runcloroude(node po)
{
int tmp;
for(int i=0;i<12;i+=4)
{
tmp=po.s[R[i]];
for(int j=0;j<3;j++)
{
po.s[R[j+i]]=po.s[R[i+j+1]];
}
po.s[R[i+3]]=tmp;
}
return po;
}

node roudeit(node po,int i)
{
switch(i)
{
case 3:return Fcloroude(po);
case 4:return Ucloroude(po);
case 5:return Rcloroude(po);
case 0:return Funcloroude(po);
case 1:return Uuncloroude(po);
case 2:return Runcloroude(po);
}
}



map<__int64,state>search1;
int stack[200],top;

//int NUM;

void bfs(node sta,node end)
{
map<__int64,state>::iterator it;
node pp,pp2;
__int64 tmppre,t1,t2,y;

queue<node>q;
q.push(sta);
q.push(end);

search1.clear();
state tmp;

tmp.pre=-1;tmp.how=-1;tmp.from=0;
search1.insert(pair<__int64,state>(sta.change(),tmp));
tmp.from=1;
search1.insert(pair<__int64,state>(end.change(),tmp));

//NUM=0;
while(!q.empty())
{
//NUM++;
pp=q.front();
q.pop();
tmppre=pp.change();
//cout<<"abx"<<endl;
//for(int i=1;i<25;i++) cout<<pp.s[i];cout<<endl;

if(pp.from)
{
for(int i=3;i<6;i++)
{
pp2=roudeit(pp,i);
y=pp2.change();
it=search1.find(y);
if(it==search1.end())
{
q.push(pp2);
tmp.pre=tmppre;
tmp.how=i;
tmp.from=pp2.from;
search1.insert(pair<__int64,state>(y,tmp));
}
else
{
if(it->second.from!=pp.from)
{
top=0;
t1=y;
while(it->second.pre!=-1)
{
stack[++top]=it->second.how;
t1=it->second.pre;
it=search1.find(t1);
}

while(top>0)
{
switch(stack[top--])
{
case 0:printf("Z");break;
case 1:printf("Y");break;
case 2:printf("X");break;
}
}

stack[++top]=i;
t2=pp.change();
it=search1.find(t2);

while(it->second.pre!=-1)
{
stack[++top]=it->second.how;
t2=it->second.pre;
it=search1.find(t2);
}

for(int j=1;j<=top;j++)
{
switch(stack[j])
{
case 3:printf("Z");break;
case 4:printf("Y");break;
case 5:printf("X");break;
}
}
//cout<<"a"<<endl;
return;
}

}
}
}
else
{
for(int i=0;i<3;i++)
{
pp2=roudeit(pp,i);
y=pp2.change();
it=search1.find(y);
if(it==search1.end())
{
q.push(pp2);
tmp.pre=tmppre;
tmp.how=i;
tmp.from=pp2.from;
search1.insert(pair<__int64,state>(y,tmp));
}
else
{
if(it->second.from!=pp.from)
{
top=0;
t2=y;
stack[++top]=i;
it=search1.find(pp.change());
while(it->second.pre!=-1)
{
stack[++top]=it->second.how;
t1=it->second.pre;
it=search1.find(t1);
}
while(top>0)
{
switch(stack[top--])
{
case 0:printf("Z");break;
case 1:printf("Y");break;
case 2:printf("X");break;
}
}
//t2=pp2.change();
it=search1.find(t2);
while(it->second.pre!=-1)
{
stack[++top]=it->second.how;
t2=it->second.pre;
it=search1.find(t2);
}
for(int j=1;j<=top;j++)
{
switch(stack[j])
{
case 3:printf("Z");break;
case 4:printf("Y");break;
case 5:printf("X");break;
}
}
//cout<<"b"<<endl;
return;
}

}
}
}
}
}



char map0[10][10];
int map1[10][10]={{0,0,1,2},{0,0,3,4},{5,6,9,10,13,14,17,18},{7,8,11,12,15,16,19,20},{0,0,21,22},{0,0,23,24}};
int numit(char w)
{
switch(w)
{
case 'G':return 0;
case 'Y':return 1;
case 'B':return 2;
case 'W':return 3;
case 'R':return 4;
case 'O':return 5;
}
}

int fd(int a,int b,int c,int d,int e)
{
if(a==c)
{
if(b==d) return e;
if(b==e) return d;
}
else if(a==d)
{
if(b==c) return e;
if(b==e) return c;
}
else if(a==e)
{
if(b==c) return d;
if(b==d) return c;
}
return -1;
}

int w[8][3]={{1,5,18},{3,6,9},{8,11,21},{4,10,13},{12,15,22},{2,14,17},{16,19,24},{7,20,23}};

int main()
{
node sta,end;
while(1)
{
for(int i=0;i<6;i++) scanf("%s",map0[i]);
if(map0[0][2]=='.') break;
for(int i=0;i<6;i++)
for(int j=0;j<8;j++)
{
if(map0[i][j]!='.')
{
sta.s[map1[i][j]]=numit(map0[i][j]);
}
}

end.s[5]=sta.s[7];
end.s[21]=sta.s[23];
end.s[17]=sta.s[20];
for(int i=0;i<7;i++)
{
if((end.s[9]=fd(end.s[5],end.s[21],sta.s[w[i][0]],sta.s[w[i][1]],sta.s[w[i][2]]))!=-1)
{
break;
}
}
for(int i=0;i<7;i++)
{
if((end.s[1]=fd(end.s[5],end.s[17],sta.s[w[i][0]],sta.s[w[i][1]],sta.s[w[i][2]]))!=-1)
{
break;
}
}
for(int i=0;i<7;i++)
{
if((end.s[13]=fd(end.s[17],end.s[21],sta.s[w[i][0]],sta.s[w[i][1]],sta.s[w[i][2]]))!=-1)
{
break;
}
}
for(int i=1;i<25;i+=4)
for(int j=1;j<4;j++) end.s[i+j]=end.s[i];
//sta.s[0]=end.s[0]='a';sta.s[25]=end.s[25]=0;
//for(int i=1;i<25;i++) cout<<sta.s[i]<<' ';cout<<endl;
//for(int j=1;j<25;j++) cout<<end.s[j]<<' ';cout<<endl;

sta.from=0;end.from=1;
bfs(sta,end);
printf("\n");
//cout<<NUM<<endl;
}
return 0;
}

 

有建议欢迎指出。

转载于:https://www.cnblogs.com/just-waiting/archive/2011/12/06/2277595.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值