二阶魔方,只有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; }
时间: 2024-10-10 14:42:07