二阶魔方,只有0,1
问最少多少步可以转成每个面都为0,或1
BFS即可,对应好旋转时候的关系,因为顺时针转三次和逆时针转1次的效果一样,所以只要6种旋转方式即可,判重可用map省空间,或者直接判省时间
#include "stdio.h"
#include "string.h"
#include "map"
#include "queue"
using namespace std;
bool mp[17000000];
struct node
{
int x[24],t;
};
int a[25];
int gethash(node cur)
{
int cnt,i;
cnt=0;
for (i=0;i<24;i++)
cnt=cnt*2+cur.x[i];
return cnt;
}
int judge(node cur)
{
int i;
for (i=0;i<24;i+=4)
if (cur.x[i]!=cur.x[i+1] || cur.x[i]!=cur.x[i+2] || cur.x[i]!=cur.x[i+3]) return -1;
return 1;
}
int bfs()
{
queue<node>q;
node cur,next;
int sum,i,temp;
sum=0;
for (i=0;i<24;i++)
{
cur.x[i]=a[i];
sum+=a[i];
}
if (sum%4!=0) return -1;
cur.t=0;
if (judge(cur)==1) return 0;
q.push(cur);
memset(mp,false,sizeof(mp));
mp[gethash(cur)]=true;
while (!q.empty())
{
cur=q.front();
q.pop();
next=cur; // 正顺
temp=next.x[0]; next.x[0]=next.x[2]; next.x[2]=next.x[3]; next.x[3]=next.x[1]; next.x[1]=temp;
temp=next.x[9]; next.x[9]=next.x[15]; next.x[15]=next.x[17];next.x[17]=next.x[4]; next.x[4]=temp;
temp=next.x[8]; next.x[8]=next.x[13]; next.x[13]=next.x[16];next.x[16]=next.x[6]; next.x[6]=temp;
temp=gethash(next);
if (mp[temp]==false)
{
mp[temp]=true;
next.t++;
if (judge(next)==1) return next.t;
q.push(next);
}
next=cur; // 正逆
temp=next.x[0]; next.x[0]=next.x[1]; next.x[1]=next.x[3]; next.x[3]=next.x[2]; next.x[2]=temp;
temp=next.x[9]; next.x[9]=next.x[4]; next.x[4]=next.x[17]; next.x[17]=next.x[15];next.x[15]=temp;
temp=next.x[8]; next.x[8]=next.x[6]; next.x[6]=next.x[16]; next.x[16]=next.x[13];next.x[13]=temp;
temp=gethash(next);
if (mp[temp]==false)
{
mp[temp]=true;
next.t++;
if (judge(next)==1) return next.t;
q.push(next);
}
next=cur; // 右侧顺
temp=next.x[4]; next.x[4]=next.x[6]; next.x[6]=next.x[7]; next.x[7]=next.x[5]; next.x[5]=temp;
temp=next.x[8]; next.x[8]=next.x[3]; next.x[3]=next.x[19]; next.x[19]=next.x[20];next.x[20]=temp;
temp=next.x[10]; next.x[10]=next.x[1]; next.x[1]=next.x[17]; next.x[17]=next.x[22];next.x[22]=temp;
temp=gethash(next);
if (mp[temp]==false)
{
mp[temp]=true;
next.t++;
if (judge(next)==1) return next.t;
q.push(next);
}
next=cur; // 右侧逆
temp=next.x[4]; next.x[4]=next.x[5]; next.x[5]=next.x[7]; next.x[7]=next.x[6]; next.x[6]=temp;
temp=next.x[8]; next.x[8]=next.x[20]; next.x[20]=next.x[19];next.x[19]=next.x[3]; next.x[3]=temp;
temp=next.x[10]; next.x[10]=next.x[22];next.x[22]=next.x[17];next.x[17]=next.x[1]; next.x[1]=temp;
temp=gethash(next);
if (mp[temp]==false)
{
mp[temp]=true;
next.t++;
if (judge(next)==1) return next.t;
q.push(next);
}
next=cur; // 上顺
temp=next.x[11]; next.x[11]=next.x[9]; next.x[9]=next.x[8]; next.x[8]=next.x[10]; next.x[10]=temp;
temp=next.x[0]; next.x[0]=next.x[4]; next.x[4]=next.x[20]; next.x[20]=next.x[12];next.x[12]=temp;
temp=next.x[1]; next.x[1]=next.x[5]; next.x[5]=next.x[21]; next.x[21]=next.x[13];next.x[13]=temp;
temp=gethash(next);
if (mp[temp]==false)
{
mp[temp]=true;
next.t++;
if (judge(next)==1) return next.t;
q.push(next);
}
next=cur; // 上逆
temp=next.x[11]; next.x[11]=next.x[10];next.x[10]=next.x[8]; next.x[8]=next.x[9]; next.x[9]=temp;
temp=next.x[0]; next.x[0]=next.x[12]; next.x[12]=next.x[20];next.x[20]=next.x[4]; next.x[4]=temp;
temp=next.x[1]; next.x[1]=next.x[13]; next.x[13]=next.x[21];next.x[21]=next.x[5]; next.x[5]=temp;
temp=gethash(next);
if (mp[temp]==false)
{
mp[temp]=true;
next.t++;
if (judge(next)==1) return next.t;
q.push(next);
}
}
return -1;
}
int main()
{
int n,i,ans;
scanf("%d",&n);
while (n--)
{
for (i=0;i<24;i++)
scanf("%d",&a[i]);
ans=bfs();
if (ans==-1)
printf("IMPOSSIBLE!\n");
else
printf("%d\n",ans);
}
return 0;
}