特殊的二街魔方

描述:

魔方大家应该都玩过。现在有一个特殊的二阶魔方,它只有一面是白色,其余五个面全是黑色。玩这个魔方当然也有特殊的规则,玩家只能通过六种方式去改变它,底层向左转一格(称为DL),底层向右转一格(称为DR),右侧向上转一格(称为RU),右侧向下转一格(称为RD),内侧顺时针转一格(称为C),内侧逆时针转一格(称为CC)。现给一魔方的状态,请在最少的步骤内把魔方还原

输入:

按照上下左右前后的顺序给出各面的具体情况,0表示白色,1表示黑色。上下、左右、前后分别是以俯视图、左视图、正视图看到的

输出:

输出令一面全为白色的最小步数。

输入样例:

00 00 11 11 11 11 11 11 11 11 11 11

输出样例:

0



#include<iostream>
#include<queue>
#include<math.h>
using namespace std;
int num[12],bai[4],ba[4],num3=0;  
//四个队列用来存放四个白块的位置,按上下左右前后的顺序对白块标号。共24个编号.
queue<int>q1;
queue<int>q2;
queue<int>q3;
queue<int>q4;

void readdata();
void init();
int bfs();
int moveto(int n);

int main()
{
 int result,i,tmp=1,flag=1,sum=0;
 
 readdata();
 
 init();
 
 for(i=0; i<11; i=i+2) //解决输入时魔方就是正常的状态
 {
  if(num[i]==0&&num[i+1]==0)
  {
   cout<<"0"<<endl;
   return 0;
  }
 }
 
 result=bfs();
 
 //判断为第几步并输出。
 for(i=1; i<10; i++)
 {
  sum=sum+pow(6,i);
  if(sum>=result)
  {
   cout<<i<<endl;
   return 0;
  }
 }
 
 return 0;
}
void readdata()
{
 int i;
 
 for(i=0; i<12; i++)
 {
  cin>>num[i];  //读入数据。
 }
}

void init()
{
 int i,j=0;
 
 for(i=0; i<12; i++)
 {
  //读到白块按顺序标号。
  if(num[i]==0)
  {
   bai[j]=i*2+1;
   j++;
   bai[j]=i*2+2;
   j++;
  }
  if(num[i]==10)
  {
   bai[j]=i*2+2;
   j++;
  }
  if(num[i]==1)
  {
   bai[j]=i*2+1;
   j++;
  }
 }
 //将白块放入队列。
 q1.push(bai[0]);
 q2.push(bai[1]);
 q3.push(bai[2]);
 q4.push(bai[3]);
}
int bfs()
{
 int i,j,tmp=0,flag=0,bug=0,bs[24];
 while(!q1.empty())
 {
  bai[0]=q1.front();
  q1.pop();
  bai[1]=q2.front();
  q2.pop();
  bai[2]=q3.front();
  q3.pop();
  bai[3]=q4.front();
  q4.pop();
  
  
  //i从0到5共6重变换方法。
  for(i=0; i<6; i++)
  {
   ba[0]=bai[0];
   ba[1]=bai[1];
   ba[2]=bai[2];
   ba[3]=bai[3];
   num3++;
   moveto(i);//经过变换后。
   
   //判百块是否在同一面,是则返回num3
   for(j=1; j<25; j++)
   {
    bs[j]=0;
   }
   for(j=0; j<4; j++)
   {
    bs[ba[j]]=1;
   }
   for(j=1; j<22; j=j+4)
   {
    if(bs[j]==1&&bs[j+1]==1&&bs[j+2]==1&&bs[j+3]==1)
    {
     return num3;
    }
   }
   
 
   q1.push(ba[0]);
   q2.push(ba[1]);
   q3.push(ba[2]);
   q4.push(ba[3]);
 
  }
 
 }
}

int moveto(int n)
{
 int i;
 //变换比较麻烦最好自己做个魔方标上号。
 if(n==0)
 {
  for(i=0; i<4; i++)
  {
   if(bai[i]==5)
   {
    ba[i]=6;
   }
   else if(bai[i]==6)
   {
    ba[i]=8;
   }
   else if(bai[i]==7)
   {
    ba[i]=5;
   }
   else if(bai[i]==8)
   {
    ba[i]=7;
   }
   else if(bai[i]==19)
   {
    ba[i]=11;
   }
   else if(bai[i]==20)
   {
    ba[i]=12;
   }
   else if(bai[i]==11)
   {
    ba[i]=24;
   }
   else if(bai[i]==12)
   {
    ba[i]=23;
   }
   else if(bai[i]==24)
   {
    ba[i]=16;
   }
   else if(bai[i]==23)
   {
    ba[i]=15;
   }
   else if(bai[i]==16)
   {
    ba[i]=19;
   }
   else if(bai[i]==15)
   {
    ba[i]=20;
   }
  }
 }
 if(n==1)
 {
  for(i=0; i<4; i++)
  {
   if(bai[i]==5)
   {
    ba[i]=7;
   }
   else if(bai[i]==6)
   {
    ba[i]=5;
   }
   else if(bai[i]==7)
   {
    ba[i]=8;
   }
   else if(bai[i]==8)
   {
    ba[i]=6;
   }
   else if(bai[i]==19)
   {
    ba[i]=16;
   }
   else if(bai[i]==20)
   {
    ba[i]=15;
   }
   else if(bai[i]==16)
   {
    ba[i]=24;
   }
   else if(bai[i]==15)
   {
    ba[i]=23;
   }
   else if(bai[i]==24)
   {
    ba[i]=11;
   }
   else if(bai[i]==23)
   {
    ba[i]=12;
   }
   else if(bai[i]==11)
   {
    ba[i]=19;
   }
   else if(bai[i]==12)
   {
    ba[i]=20;
   }
  }
 }
 if(n==2)
 {
  for(i=0; i<4; i++)
  {
   if(bai[i]==13)
   {
    ba[i]=15;
   }
   else if(bai[i]==14)
   {
    ba[i]=13;
   }
   else if(bai[i]==15)
   {
    ba[i]=16;
   }
   else if(bai[i]==16)
   {
    ba[i]=14;
   }
   else if(bai[i]==2)
   {
    ba[i]=24;
   }
   else if(bai[i]==4)
   {
    ba[i]=22;
   }
   else if(bai[i]==24)
   {
    ba[i]=8;
   }
   else if(bai[i]==22)
   {
    ba[i]=6;
   }
   else if(bai[i]==8)
   {
    ba[i]=18;
   }
   else if(bai[i]==6)
   {
    ba[i]=20;
   }
   else if(bai[i]==18)
   {
    ba[i]=2;
   }
   else if(bai[i]==20)
   {
    ba[i]=4;
   }
  }
 }
 if(n==3)
 {
  for(i=0; i<4; i++)
  {
   if(bai[i]==13)
   {
    ba[i]=14;
   }
   else if(bai[i]==14)
   {
    ba[i]=16;
   }
   else if(bai[i]==15)
   {
    ba[i]=13;
   }
   else if(bai[i]==16)
   {
    ba[i]=15;
   }
   else if(bai[i]==2)
   {
    ba[i]=18;
   }
   else if(bai[i]==4)
   {
    ba[i]=20;
   }
   else if(bai[i]==18)
   {
    ba[i]=8;
   }
   else if(bai[i]==20)
   {
    ba[i]=6;
   }
   else if(bai[i]==8)
   {
    ba[i]=24;
   }
   else if(bai[i]==6)
   {
    ba[i]=22;
   }
   else if(bai[i]==24)
   {
    ba[i]=2;
   }
   else if(bai[i]==22)
   {
    ba[i]=4;
   }
  }
 }
 if(n==4)
 {
  for(i=0; i<4; i++)
  {
   if(bai[i]==17)
   {
    ba[i]=18;
   }
   else if(bai[i]==18)
   {
    ba[i]=20;
   }
   else if(bai[i]==19)
   {
    ba[i]=17;
   }
   else if(bai[i]==20)
   {
    ba[i]=19;
   }
   else if(bai[i]==3)
   {
    ba[i]=14;
   }
   else if(bai[i]==4)
   {
    ba[i]=16;
   }
   else if(bai[i]==14)
   {
    ba[i]=8;
   }
   else if(bai[i]==16)
   {
    ba[i]=7;
   }
   else if(bai[i]==8)
   {
    ba[i]=12;
   }
   else if(bai[i]==7)
   {
    ba[i]=10;
   }
   else if(bai[i]==12)
   {
    ba[i]=3;
   }
   else if(bai[i]==10)
   {
    ba[i]=4;
   }
  }
 }
 if(n==5)
 {
  for(i=0; i<4; i++)
  {
   if(bai[i]==17)
   {
    ba[i]=19;
   }
   else if(bai[i]==18)
   {
    ba[i]=17;
   }
   else if(bai[i]==19)
   {
    ba[i]=20;
   }
   else if(bai[i]==20)
   {
    ba[i]=18;
   }
   else if(bai[i]==3)
   {
    ba[i]=12;
   }
   else if(bai[i]==4)
   {
    ba[i]=10;
   }
   else if(bai[i]==12)
   {
    ba[i]=8;
   }
   else if(bai[i]==10)
   {
    ba[i]=7;
   }
   else if(bai[i]==8)
   {
    ba[i]=14;
   }
   else if(bai[i]==7)
   {
    ba[i]=16;
   }
   else if(bai[i]==14)
   {
    ba[i]=3;
   }
   else if(bai[i]==16)
   {
    ba[i]=4;
   }
  }
 }
}


                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值