异形魔方SQ1的暴力解法
异形魔方的算法。by @沉默de世界
这个是暴力破解,打乱试了几次,一种用了7步还原,一种用了6步还原,估计大部分状态10步以内可以还原,超过10步计算就比较费时了。
说明如图:(1)编号如图所示,上层12345678 下层11,12,13,14,15,16,17,18 。
(2)R1动作为线前侧(图中5,6,7,8,14,15,16,17位置)旋转180度,R2为线前侧(7,6,5,4,18,17,16,15位置)旋转,R3为线右侧(3,4,5,6,12,13,14,15位置)旋转,R4为线右侧(5,4,3,2,16,15,14,13)旋转。
(3)R5、R6、R7、R8分别对应上层顺时针旋转90度后执行R1、R2、R3、R4。
(4)R9、R10、R11、R12分别对应上层顺时针旋转180度后执行R1、R2、R3、R4。
(5)R13、R14、R15、R16分别对应上层顺时针旋转270度后执行R1、R2、R3、R4。
(6)打乱状态starta,startb分别为上下两层、从左上角开始、按顺时针顺序的块编号,改程序中初始值即可。在以上转动过程中编号11的块位置是始终保持不变的。
//written by @沉默de世界
#include "stdafx.h" #include "stdio.h" #define DEEP_MAX 20 //70*6 * 70*6 *4 * 6*6*4 typedef struct _CUBE_STATUS{ int a[8]; int b[8]; }CUBE_STATUS; CUBE_STATUS cb0,cb1,cb; int succflag=0; int act[DEEP_MAX]={0}; int deep_i=-1; int deep_max=-1; int deep_reuslt=0; void cpy(CUBE_STATUS *p1, CUBE_STATUS *p0); void pntcb(CUBE_STATUS *p); void Rot(CUBE_STATUS *p); void Rn(CUBE_STATUS *p,int n); int IsSame(CUBE_STATUS *p1,CUBE_STATUS *p2); int main(int argc, char* argv[]) { // int starta[8]={3,4,5,6,17,16,15,14}; // int startb[8]={11,12,13,2,1,8,7,18}; // int starta[8]={1,2,3,4,5,16,7,8}; // int startb[8]={11,12,13,14,17,6,15,18}; int starta[8]={5,14,3,16, 15,6,7,8}; int startb[8]={11,12,13,2, 1,4,17,18}; int i=0; for (i=0;i<8;i++) { cb0.a[i]=i+1;//目标状态 cb0.b[i]=i+11;
cb1.a[i]=starta[i];//初始状态 cb1.b[i]=startb[i]; cb.a[i]=starta[i]; cb.b[i]=startb[i]; } printf("start...\n"); if(IsSame(&cb,&cb0)) succflag=1; else { for (deep_i=0,deep_max=1;deep_max<=DEEP_MAX;deep_max++) { printf("\nMAXDEEP: %d \n",deep_max); Rot(&cb); if(succflag==1)break; } } if(succflag==1) { printf("\nSucceed! It need %d steppes. \n",deep_reuslt); printf("start:"); pntcb(&cb1); for (i=0;i<deep_reuslt;i++) { Rn(&cb1,act[i]); printf("R%-2d-> ",act[i]); pntcb(&cb1); } } else printf("failed!\n"); return 0; } void Rot(CUBE_STATUS *p) { int i; if(deep_i>=deep_max) return; for (i=1;i<=16;i++) { CUBE_STATUS tmp; if( deep_i>0 ) { if ( ( i==1 && (act[deep_i-1]==1 || act[deep_i-1]==5 || act[deep_i-1]==9 || act[deep_i-1]==13) ) || ( i==2 && (act[deep_i-1]==2 || act[deep_i-1]==6 || act[deep_i-1]==10 || act[deep_i-1]==14) ) || ( i==3 && (act[deep_i-1]==3 || act[deep_i-1]==7 || act[deep_i-1]==11 || act[deep_i-1]==15) ) || ( i==4 && (act[deep_i-1]==4 || act[deep_i-1]==8 || act[deep_i-1]==12 || act[deep_i-1]==16) ) ) continue; } cpy(&tmp,p); Rn(&tmp,i); act[deep_i]=i; if(IsSame(&tmp,&cb0)) { succflag=1; deep_reuslt=deep_i+1; return; } else { deep_i++; Rot(&tmp); deep_i--; if(succflag==1) { return; } } } } int IsSame(CUBE_STATUS *p1,CUBE_STATUS *p2) { if( (p1->b[0]==p2->b[0] && p1->b[1]==p2->b[1] && p1->b[2]==p2->b[2] && p1->b[3]==p2->b[3] && p1->b[4]==p2->b[4] && p1->b[5]==p2->b[5] && p1->b[6]==p2->b[6] && p1->b[7]==p2->b[7] ) && ( (p1->a[0]==p2->a[0] && p1->a[1]==p2->a[1] && p1->a[2]==p2->a[2] && p1->a[3]==p2->a[3] && p1->a[4]==p2->a[4] && p1->a[5]==p2->a[5] && p1->a[6]==p2->a[6] && p1->a[7]==p2->a[7]) || (p1->a[0]==p2->a[2] && p1->a[1]==p2->a[3] && p1->a[2]==p2->a[4] && p1->a[3]==p2->a[5] && p1->a[4]==p2->a[6] && p1->a[5]==p2->a[7] && p1->a[6]==p2->a[0] && p1->a[7]==p2->a[1]) || (p1->a[0]==p2->a[4] && p1->a[1]==p2->a[5] && p1->a[2]==p2->a[6] && p1->a[3]==p2->a[7] && p1->a[4]==p2->a[0] && p1->a[5]==p2->a[1] && p1->a[6]==p2->a[2] && p1->a[7]==p2->a[3]) || (p1->a[0]==p2->a[6] && p1->a[1]==p2->a[7] && p1->a[2]==p2->a[0] && p1->a[3]==p2->a[1] && p1->a[4]==p2->a[2] && p1->a[5]==p2->a[3] && p1->a[6]==p2->a[4] && p1->a[7]==p2->a[5]) ) ) return 1; else return 0; } void R90(CUBE_STATUS *p) { int t0=0,t1=0; t0=p->a[0]; t1=p->a[1]; p->a[0]=p->a[6]; p->a[1]=p->a[7]; p->a[6]=p->a[4]; p->a[7]=p->a[5]; p->a[4]=p->a[2]; p->a[5]=p->a[3]; p->a[2]=t0; p->a[3]=t1; } void R180(CUBE_STATUS *p) { int t0=0,t1=0,t2=0,t3=0; t0=p->a[0]; t1=p->a[1]; t2=p->a[2]; t3=p->a[3]; p->a[0]=p->a[4]; p->a[1]=p->a[5]; p->a[2]=p->a[6]; p->a[3]=p->a[7]; p->a[4]=t0; p->a[5]=t1; p->a[6]=t2; p->a[7]=t3; } void R270(CUBE_STATUS *p) { int t0=0,t1=0; t0=p->a[0]; t1=p->a[1]; p->a[0]=p->a[2]; p->a[1]=p->a[3]; p->a[2]=p->a[4]; p->a[3]=p->a[5]; p->a[4]=p->a[6]; p->a[5]=p->a[7]; p->a[6]=t0; p->a[7]=t1; } void R1(CUBE_STATUS *p) { int ta7,ta6,ta5,ta4; ta7=p->a[7]; ta6=p->a[6]; ta5=p->a[5]; ta4=p->a[4]; p->a[7]=p->b[3]; p->a[6]=p->b[4]; p->a[5]=p->b[5]; p->a[4]=p->b[6]; p->b[3]=ta7; p->b[4]=ta6; p->b[5]=ta5; p->b[6]=ta4; } void R2(CUBE_STATUS *p) { int ta6,ta5,ta4,ta3; ta6=p->a[6]; ta5=p->a[5]; ta4=p->a[4]; ta3=p->a[3]; p->a[6]=p->b[4]; p->a[5]=p->b[5]; p->a[4]=p->b[6]; p->a[3]=p->b[7]; p->b[4]=ta6; p->b[5]=ta5; p->b[6]=ta4; p->b[7]=ta3; } void R3(CUBE_STATUS *p) { int ta2,ta5,ta4,ta3; ta5=p->a[5]; ta4=p->a[4]; ta3=p->a[3]; ta2=p->a[2]; p->a[5]=p->b[1]; p->a[4]=p->b[2]; p->a[3]=p->b[3]; p->a[2]=p->b[4]; p->b[1]=ta5; p->b[2]=ta4; p->b[3]=ta3; p->b[4]=ta2; } void R4(CUBE_STATUS *p) { int ta2,ta1,ta4,ta3; ta1=p->a[1]; ta4=p->a[4]; ta3=p->a[3]; ta2=p->a[2]; p->a[4]=p->b[2]; p->a[3]=p->b[3]; p->a[2]=p->b[4]; p->a[1]=p->b[5]; p->b[2]=ta4; p->b[3]=ta3; p->b[4]=ta2; p->b[5]=ta1; } void Rn(CUBE_STATUS *p,int n) { switch(n) { //case 0: R0(p);break; case 1: R1(p);break; case 2: R2(p);break; case 3: R3(p);break; case 4: R4(p);break; case 5: R90(p);R1(p);break; case 6: R90(p);R2(p);break; case 7: R90(p);R3(p);break; case 8: R90(p);R4(p);break; case 9: R180(p);R1(p);break; case 10: R180(p);R2(p);break; case 11: R180(p);R3(p);break; case 12: R180(p);R4(p);break; case 13: R270(p);R1(p);break; case 14: R270(p);R2(p);break; case 15: R270(p);R3(p);break; case 16: R270(p);R4(p);break; default: ; } } void cpy(CUBE_STATUS *p1, CUBE_STATUS *p0) { for (int i=0;i<8;i++) { p1->a[i]=p0->a[i]; p1->b[i]=p0->b[i]; } } void pntcb(CUBE_STATUS *p) { for (int j=0;j<8;j++) { printf("%d, ",p->a[j]); } printf(" "); for (j=0;j<8;j++) { printf("%d, ",p->b[j]); } printf("\n"); }