標籤:
二階魔方,只有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;}
2013山東省賽Rubik’s cube 魔方BFS