2阶魔方的复原的BFS写法。。。。

原创 2013年12月03日 11:24:35

二阶魔方:

8个角块的位置均可进行任意互换(8!种状态),如果以一个角块不动作为参考角块,其他7个角块都能任意转换方向(即37种状态)。如果在空间中旋转则不计算方向不同而状态相同的魔方,实际上的准确状态数还应除以24。所以二阶魔方的总状态数应该为:

\frac{8!\,3^7}{24}=7!\,3^6=3674160

二阶魔方的最远复原距离(即最需要最多步骤复原的状态)为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;
}


版权声明:来自: 码代码的猿猿的AC之路 http://blog.csdn.net/ck_boss

相关文章推荐

css3实现简易魔方

demo .stage{ position:relative; top:50px; } .box_before,.box_back,.box_left,.box_right,.box_top,...

二阶魔方旋转 魔方可以对它的6个面自由旋转。 我们来操作一个2阶魔方(如图1所示):

/* 二阶魔方旋转 魔方可以对它的6个面自由旋转。 我们来操作一个2阶魔方(如图1所示): 为了描述方便,我们为它建立了坐标系。 各个面的初始状态如下: x轴正向:绿 x轴反向:蓝 ...

HDU 5250 三阶魔方(模拟、置换)

题意: 给定N≤100的三阶魔方操作序列给定N\le100的三阶魔方操作序列 魔方操作如下图:魔方操作如下图: 求问:对一个初状态(六个面都是拼好的)的魔方进行多少次连续的序列...
  • lwt36
  • lwt36
  • 2016年02月12日 00:03
  • 564

ZOJ 2477 Magic Cube 三阶魔方还原(IDA*)

转载请注明出处,谢谢 http://blog.csdn.net/ACM_cxlove?viewmode=contents           by---cxlove 三阶魔方还原。因为只搜5层,...

三阶魔方CFOP复原的C语言算法

/******************************************************************/ /** brief: 三阶魔方CFOP四步还原 ...

三阶四阶魔方自动复原程序(Java)

本人刚刚接触java不久,大概学了3个月,自行编写了一个三阶四阶mofang

四阶魔方复原简单的一种方法

  • 2010年04月30日 23:23
  • 1.52MB
  • 下载

BNUOJ 51277 魔方复原(模拟、置换)

题意: 给定N≤105的三阶魔方操作序列给定N\le10^5的三阶魔方操作序列 由U、D、R、L、F、B操作构成,如下图:由U、D、R、L、F、B操作构成,如下图: 操作序列表...
  • lwt36
  • lwt36
  • 2016年02月11日 23:57
  • 331

不看公式自己复原魔方

2、3阶完成         网上很容易找到魔方公式,所以复原魔方已经变成了一种记忆,而不再试游戏,我感觉按公式复原魔方是一种玩法,快速复原魔方是一种乐趣。对我来说,自己复原魔方,这里面有另外的乐趣...
  • buck84
  • buck84
  • 2013年03月17日 23:48
  • 4755

java 魔方小程序。只拧红、蓝、白三色。大概8秒内复原。拧1亿次左右

菜鸟娱乐的。import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; impo...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:2阶魔方的复原的BFS写法。。。。
举报原因:
原因补充:

(最多只允许输入30个字)