二阶魔方:
8个角块的位置均可进行任意互换(8!种状态),如果以一个角块不动作为参考角块,其他7个角块都能任意转换方向(即37种状态)。如果在空间中旋转则不计算方向不同而状态相同的魔方,实际上的准确状态数还应除以24。所以二阶魔方的总状态数应该为:
二阶魔方的最远复原距离(即最需要最多步骤复原的状态)为11次全旋转,或者14次普通旋转,此结果可以用计算机使用Brute Force算法计算出。
旋转次数 | 进行全旋转复原的魔方的状态数 | 进行普通旋转复原的魔方的状态数 |
---|---|---|
0 | 1 | 1 |
1 | 9 | 6 |
2 | 54 | 27 |
3 | 321 | 120 |
4 | 1847 | 534 |
5 | 9992 | 2256 |
6 | 50136 | 8969 |
7 | 227536 | 33058 |
8 | 870072 | 114149 |
9 | 1887748 | 360508 |
10 | 623800 | 930588 |
11 | 2644 | 1350852 |
12 | 782536 | |
13 | 90280 | |
14 | 276 |
虽然复原距离不是很大,但是用BFS的话效率还是太低了。。。。把数据输入进去,然后就可以喝茶了。。。。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <queue>
#include <set>
#include <vector>
using namespace std;
struct MuoFang
{
int mf[24],cur;
string cmd;
vector<int> nc;
}M;
string q1("前1 "),q2("前2 "),z1("左1 "),z2("左2 "),s1("上1 "),s2("上2 ");
string _0("0"),_1("1"),_2("2"),_3("3"),_4("4"),_5("5");
set<string> st;
bool _ck(MuoFang M,int a,int b,int c,int d)
{
if(M.mf[a]==M.mf[b]&&M.mf[a]==M.mf[c]&&M.mf[a]==M.mf[d]) return true;
return false;
}
bool ck(MuoFang M)
{
if(_ck(M,0,1,2,3)&&_ck(M,4,5,10,11)&&_ck(M,6,7,12,13)&&_ck(M,8,9,14,15)&&_ck(M,16,17,18,19)&&_ck(M,20,21,22,23))
return true;
return false;
}
int count_ck(MuoFang M)
{
return _ck(M,0,1,2,3)+_ck(M,4,5,10,11)+_ck(M,6,7,12,13)+_ck(M,8,9,14,15)+_ck(M,16,17,18,19)+_ck(M,20,21,22,23);
}
MuoFang zhuan(MuoFang M,int a,int b,int c,int d, int e,int f, int g,int h, int i,int j, int k,int l)
{
///圈
int t=M.mf[a];
M.mf[a]=M.mf[d];M.mf[d]=M.mf[c];M.mf[c]=M.mf[b];M.mf[b]=t;
///环
int t1=M.mf[e],t2=M.mf[f];
M.mf[e]=M.mf[g];M.mf[f]=M.mf[h];
M.mf[g]=M.mf[i];M.mf[h]=M.mf[j];
M.mf[i]=M.mf[k];M.mf[j]=M.mf[l];
M.mf[k]=t1;M.mf[l]=t2;
return M;
}
MuoFang qian1(MuoFang M)
{
return zhuan(M,13,12,6,7,3,2,5,11,16,17,14,8);
}
MuoFang qian2(MuoFang M)
{
return zhuan(M,6,12,13,7,2,3,8,14,17,16,11,5);
}
MuoFang zhuo1(MuoFang M)
{
return zhuan(M,15,14,8,9,1,3,7,13,17,19,21,23);
}
MuoFang zhuo2(MuoFang M)
{
return zhuan(M,8,14,15,9,23,21,19,17,13,7,3,1);
}
MuoFang shang1(MuoFang M)
{
return zhuan(M,16,17,19,18,20,21,15,14,13,12,11,10);
}
MuoFang shang2(MuoFang M)
{
return zhuan(M,16,18,19,17,10,11,12,13,14,15,21,20);
}
string gethash(MuoFang M)
{
string hh;
for(int i=0;i<=23;i++)
{
if(M.mf[i]==0) hh+=_0;
else if(M.mf[i]==1) hh+=_1;
else if(M.mf[i]==2) hh+=_2;
else if(M.mf[i]==3) hh+=_3;
else if(M.mf[i]==4) hh+=_4;
else if(M.mf[i]==5) hh+=_5;
}
return hh;
}
bool panchong(MuoFang u)
{
string hh=gethash(u);
if(st.count(hh)) return false;
st.insert(hh);
// cout<<"---> "<<hh<<endl;
return true;
}
int ans=0;
void bfs()
{
void show(MuoFang m);
queue<MuoFang> q;
st.clear();
MuoFang u,v,TM;
q.push(M);TM=M;
panchong(M);
bool flag=false;
while(!q.empty())
{
u=q.front(); q.pop();
// cout<<" "<<q.size()<<endl;
// cout<<gethash(u)<<endl;
if(count_ck(u)==6) {flag=true;break;}
v=qian1(u);
if(panchong(v))
{
v.cur++;v.cmd+=q1;v.nc.push_back(11); if(v.cur<15) q.push(v);
}
v=qian2(u);
if(panchong(v))
{
v.cur++;v.cmd+=q2;v.nc.push_back(12); if(v.cur<15) q.push(v);
}
v=zhuo1(u);
if(panchong(v))
{
v.cur++;v.cmd+=z1;v.nc.push_back(21); if(v.cur<15) q.push(v);
}
v=zhuo2(u);
if(panchong(v))
{
v.cur++;v.cmd+=z2;v.nc.push_back(22); if(v.cur<15) q.push(v);
}
v=shang1(u);
if(panchong(v))
{
v.cur++;v.cmd+=s1;v.nc.push_back(31); if(v.cur<15) q.push(v);
}
v=shang2(u);
if(panchong(v))
{
v.cur++;v.cmd+=s2;v.nc.push_back(32); if(v.cur<15) q.push(v);
}
}
if(flag)
{
cout<<"Let's do: \n";
show(TM);
cout<<u.cmd<<endl;
int t=u.nc.size();
for(int i=0;i<t;i++)
{
if(u.nc[i]==11)
{
TM=qian1(TM); show(TM);
}
else if(u.nc[i]==12)
{
TM=qian2(TM); show(TM);
}
else if(u.nc[i]==21)
{
TM=zhuo1(TM); show(TM);
}
else if(u.nc[i]==22)
{
TM=zhuo2(TM); show(TM);
}
else if(u.nc[i]==31)
{
TM=shang1(TM); show(TM);
}
else if(u.nc[i]==32)
{
TM=shang2(TM); show(TM);
}
}
putchar(10);
}
else puts("error data");
}
void show(MuoFang M)
{
cout<<" "<<M.mf[0]<<" "<<M.mf[1]<<endl;
cout<<" "<<M.mf[2]<<" "<<M.mf[3]<<endl;
cout<<M.mf[4]<<" "<<M.mf[5]<<" "<<M.mf[6]<<" "<<M.mf[7]<<" "<<M.mf[8]<<" "<<M.mf[9]<<endl;
cout<<M.mf[10]<<" "<<M.mf[11]<<" "<<M.mf[12]<<" "<<M.mf[13]<<" "<<M.mf[14]<<" "<<M.mf[15]<<endl;
cout<<" "<<M.mf[16]<<" "<<M.mf[17]<<endl;
cout<<" "<<M.mf[18]<<" "<<M.mf[19]<<endl;
cout<<" "<<M.mf[20]<<" "<<M.mf[21]<<endl;
cout<<" "<<M.mf[22]<<" "<<M.mf[23]<<endl;
cout<<"-------------------\n";
}
int main()
{
while(true)
{
for(int i=0;i<24;i++) scanf("%d",&M.mf[i]);
//cout<<gethash(M)<<endl;
M.cur=0;
ans=count_ck(M);
if(ans==6) puts("DONE");
bfs();
}
return 0;
}