大致题意:

题目描述 口袋魔方又称为迷你魔方,通俗的来讲就是二阶魔方,只有八个角块的魔方,如图所示。 二阶魔方8个角块的位置均可进行任意互换(8!种状态),如果以一个角块不动作为参考角块,其他7个 角块都能任意转换方向(即37种状态)。如果在空间中旋转则不计算方向不同而状态相同的魔方,实际上的准确 状态数还应除以24。所以二阶魔方的总状态数为: 7!*3^6=3674160。二阶魔方的最远复原距离(即最需要最多 步骤复原的状态)为11次全旋转,或者14次普通旋转,此结果可以用暴力穷举算法计算出 下面给你一个口袋魔方,只需要进行一些简单的处理就能解决这道题了。对于此魔方的任意一个面,你可以选择 顺时针旋转或者逆时针进行一次90度的旋转,如果能够进行不超过一次的旋转操作,就能使此魔方复原(每面内 部颜色相同,共六种颜色),那么请输出“我真是个小机灵鬼!”,否则请输出“这个魔方有bug!”。 输入 第一行一个T,代表测试实例数。 每个测试实例有6行输入。 每行4个整数,代表相应位置的颜色 输入数字位置对应下面魔方展开图。 如a代表输入的第一个整数所在位置,其他同上。 + - + - + - + - + - + - + | q | r | a | b | u | v | + - + - + - + - + - + - + | s | t | c | d | w | x | + - + - + - + - + - + - + | e | f | + - + - + | g | h | + - + - + | i | j | + - + - + | k | l | + - + - + | m | n | + - + - + | o | p | + - + - + 输出 如题。 样例输入 4 1 1 1 1 2 2 2 2 3 3 3 3 4 4 4 4 5 5 5 5 6 6 6 6 6 6 6 6 1 1 1 1 2 2 2 2 3 3 3 3 5 5 5 5 4 4 4 4 1 4 1 4 2 1 2 1 3 2 3 2 4 3 4 3 5 5 5 5 6 6 6 6 1 3 1 3 2 4 2 4 3 1 3 1 4 2 4 2 5 5 5 5 6 6 6 6 样例输出 我真是个小机灵鬼! 我真是个小机灵鬼! 我真是个小机灵鬼! 这个魔方有bug!
大致思路:
1.枚举全部地旋转方法,共八种: 顺时针 : 横一层/横二层/竖一层/竖二层 / 侧一层/侧二层
同时逆时针,全部都对应一个;共16种!
2. 每次旋转,只转动一层的八个格点而已 ; 八个格点只需要顺序或者逆序排序一下然后赋值即可!
3.每旋转一次, 每个面上相邻的两个不用考虑顺序,因为这两个毕竟顺着方向上的旋转下是绑定在一起的!
4/繁琐的东西用函数实现, 把一个大问题化解成小问题!
5/注意把他们展开后,记得画图!用线顺时针在平面图上用线顺时针连起来! 后面的那个格子上下是颠倒的!串线的时候需要注意三维空间的真实情况!!
题解:

1 #include<bits/stdc++.h> 2 using namespace std; 3 #define inf 0x3f3f3f3f 4 #define N 50008 5 #define ll long long 6 #define mem(a,x) memset(a,x,sizeof(a)) ///问题 C: 签到(sign) 7 int a[100]; //存每个面的颜色 8 int mp1[10][10]={ 9 {1,2,3,4}, 10 {5,6,7,8}, 11 {9,10,11,12}, 12 {13,14,15,16}, 13 {17,18,19,20}, 14 {21,22,23,24} 15 }; 16 int mp2[10][10]={ 17 {17,18,1,2,21,22,11,12}, //y=1&2 18 {19,20,3,4,23,24,9,10}, 19 {1,3,5,7,9,11,13,15}, //rotate(),x=1&x=2 20 {2,4,6,8,10,12,14,16}, 21 {18,20,15,16,21,23,5,6}, 22 {17,19,13,14,22,24,7,8} 23 }; 24 25 void Rotate(int k,int mode){ //转动第k行mp2[]的列表 ,mode=0顺,mode=1表示逆 26 vector<int>ans; 27 for(int i=0;i<8;i++){ 28 int x=mp2[k][i]; 29 ans.push_back(a[x]); 30 } 31 32 if(mode==0){ 33 ans.push_back(ans[0]); 34 ans.push_back(ans[1]); 35 ans.erase(ans.begin(),ans.begin()+2); 36 37 for(int i=0;i<8;i++){ 38 int x=mp2[k][i]; 39 a[x]=ans[i]; 40 } 41 } 42 else{ 43 int x=ans[7],y=ans[6]; 44 ans.insert(ans.begin(),x); 45 ans.insert(ans.begin(),y); 46 ans.erase(ans.end()-2,ans.end()); 47 for(int i=0;i<8;i++){ 48 int x=mp2[k][i]; 49 a[x]=ans[i]; 50 } 51 } 52 } 53 bool judge(){ 54 for(int i=0;i<6;i++){ 55 int mx=-10000,minn=inf; 56 for(int j=0;j<4;j++){ 57 int x=mp1[i][j]; 58 mx=max(mx,a[x]); 59 minn=min(minn,a[x]); 60 } 61 if(mx!=minn)return 0; 62 } 63 return 1; 64 } 65 //void debug(){ 66 // printf("%3d %3d %3d %3d %3d %3d ",a[17],a[18],a[1],a[2],a[21],a[22]); 67 // printf("%3d %3d %3d %3d %3d %3d ",a[19],a[20],a[3],a[4],a[23],a[24]); 68 // printf(" %3d %3d %3d %3d ",a[5],a[6],a[7],a[8]); 69 // printf(" %3d %3d %3d %3d ",a[9],a[10],a[11],a[12]); 70 // printf(" %3d %3d %3d %3d ",a[13],a[14],a[15],a[16]); 71 // printf("________ "); 72 //} 73 void debug(){ 74 cout<<endl; 75 for(int i=1;i<=24;i++) 76 printf("%d%c",a[i],i%4==0?' ':' '); 77 cout<<endl; 78 } 79 int main(){ 80 int T; 81 scanf("%d",&T); 82 while(T--){ 83 a[0]=-1; 84 for(int i=1;i<=24;i++) 85 scanf("%d",&a[i]); 86 87 // bool f=0; 88 // for(int i=0;!f&&i<6;i++) //mode=0 89 // { 90 // Rotate(i,0); 91 // if(judge()==1)f=1;debug(); 92 // Rotate(i,1); 93 // Rotate(i,1); 94 // if(judge()==1)f=1;debug(); 95 // Rotate(i,0); 96 // // if(judge()==0)printf("i1=%d,66666666 ",i); 97 // } 98 99 if(judge()==1){ 100 printf("我真是个小机灵鬼! "); 101 } 102 else{ 103 bool f=0; 104 for(int i=0;!f&&i<6;i++) //mode=0 105 { 106 Rotate(i,0); 107 if(judge()==1)f=1; 108 Rotate(i,1); 109 // if(judge()==0)printf("i1=%d,66666666 ",i); 110 } 111 for(int i=0;!f&&i<6;i++) //mode=1 112 { 113 Rotate(i,1); 114 if(judge()==1)f=1; 115 Rotate(i,0); 116 // if(judge()==0)printf("i1=%d,66666666 ",i); 117 } 118 if(!f) 119 printf("这个魔方有bug! "); 120 else 121 printf("我真是个小机灵鬼! "); 122 } 123 } 124 125 return 0; 126 }
当然,我第一次不是这么写的!我是把所有的16种情况,每种情况单写一个函数解决的!
写到第8个时,发现正着和逆着旋转某个角度其实可以化简,就回头看看,加了个op=-1!
题解:(写了六个小时!!)

#include<stdio.h> #include<string.h> #include<math.h> #include<iostream> #include<algorithm> #include<queue> using namespace std; #define inf 0x3f3f3f3f #define N 110 char str[N]; ///第一维表示魔方的面 int mp[10][20]= { {1,2,2, 2,2,2, 1,1,2, 2,1,2}, ///总共六个面,下标0-5 face_id {1,1,2, 2,1,2, 1,1,1, 2,1,1}, {1,1,1, 2,1,1, 1,2,1, 2,2,1}, {1,2,1, 2,2,1, 1,2,2, 2,2,2}, {1,2,1, 1,2,2, 1,1,1, 1,1,2}, {2,2,2, 2,2,1, 2,1,2, 2,1,1} }; struct node{ int x,y,z,Face; node(int x=0,int y=0,int z=0,int Face=0):x(x),y(y),z(z),Face(Face){} }; int a[10][10][10][10]; ///四维对应 x-y-z- face_id bool judge() ///判断是否达成魔方的要求 { for(int i=0; i<=5; i++) //总共六个面 { int minn=999,maxx=-1; for(int j=1; j<=4; j++) { int x=mp[i][j*3-3]; int y=mp[i][j*3-2]; int z=mp[i][j*3-1]; minn=min(minn, a[x][y][z][i]); maxx=max(maxx, a[x][y][z][i]); } if(minn!=maxx)return false; } return true; } void debug(vector<int>st,int mode){ cout<<"_______________***"<<"mode="<<mode<<endl; for(int i=0; i<=5; i++) //总共六个面 { for(int j=1; j<=4; j++) { int x=mp[i][j*3-3]; int y=mp[i][j*3-2]; int z=mp[i][j*3-1]; cout<<a[x][y][z][i]<<" "; ///四维对应 x-y-z- face_id } cout<<endl; } cout<<"***"<<"st_list__"<<endl; for(int i=0;i<(int)st.size();i++){ if((i+1)%4==0) printf(" %d ** ",st[i]); else printf(" %d",st[i]); } cout<<endl; } void rotating(int mode){ vector<int>st; int op=1; if(mode==0||mode==1){ for(int i=0; i<=3; i++) //总共六个面 { for(int j=1; j<=4; j+=2) { int x=mp[i][j*3-3];int y=mp[i][j*3-2];int z=mp[i][j*3-1]; st.push_back(a[x][y][z][i]); } } int len=st.size(),cnt=0; if(mode==1)op=-1; for(int i=0; i<=3; i++) //总共4个面,只取两个即可 { for(int j=1; j<=4; j+=2) { int x=mp[i][j*3-3];int y=mp[i][j*3-2];int z=mp[i][j*3-1]; a[x][y][z][i] = st[(cnt-2*op+len)%len] ; ///x=1的四块,shun/ni时针 cnt++; } } } else if(mode == 2 || mode==3){ for(int i=0; i<=3; i++){ //总共4个面 for(int j=2; j<=4; j+=2){ int x=mp[i][j*3-3];int y=mp[i][j*3-2];int z=mp[i][j*3-1]; st.push_back(a[x][y][z][i]); } } int len=st.size(),cnt=0; if(mode==3)op=-1; for(int i=0; i<=3; i++){ //总共4个面,只取两个即可 for(int j=2; j<=4; j+=2){ int x=mp[i][j*3-3];int y=mp[i][j*3-2];int z=mp[i][j*3-1]; a[x][y][z][i] = st[(cnt-2*op+len)%len] ;///x=2的四块,shun/ni时针 cnt++; } } } else if(mode==4||mode==5){ int ii[]={0,5,2,4}; for(int k=0; k<=3; k++){ //总共4个面 if(ii[k]==2){ for(int j=1; j<=2; j++){ int i=ii[k]; int x=mp[i][j*3-3];int y=mp[i][j*3-2];int z=mp[i][j*3-1]; st.push_back(a[x][y][z][i]); } continue; } for(int j=3; j<=4; j++){ int i=ii[k]; int x=mp[i][j*3-3];int y=mp[i][j*3-2];int z=mp[i][j*3-1]; st.push_back(a[x][y][z][i]); } } int len=st.size(),cnt=0; if(mode==5)op=-1; for(int k=0; k<=3; k++){ //总共4个面,只取两个即可 if(ii[k]==2){ for(int j=1; j<=2; j++){ int i=ii[k]; int x=mp[i][j*3-3];int y=mp[i][j*3-2];int z=mp[i][j*3-1]; a[x][y][z][i] = st[(cnt+2*op+len)%len] ; cnt++; } continue; } for(int j=3; j<=4; j++){ int i=ii[k]; int x=mp[i][j*3-3];int y=mp[i][j*3-2];int z=mp[i][j*3-1]; a[x][y][z][i] = st[(cnt+2*op+len)%len] ;///y=1的四块,shun/ni时针 cnt++; } } } else if(mode==6||mode==7){ ///y=2, 3,4,1,2 int ii[]={0,5,2,4}; for(int k=0; k<=3; k++){ //总共4个面 if(ii[k]==2){ for(int j=3; j<=4; j++){ int i=ii[k]; int x=mp[i][j*3-3];int y=mp[i][j*3-2];int z=mp[i][j*3-1]; st.push_back(a[x][y][z][i]); } continue; } for(int j=1; j<=2; j++){ int i=ii[k]; int x=mp[i][j*3-3];int y=mp[i][j*3-2];int z=mp[i][j*3-1]; st.push_back(a[x][y][z][i]); } } int len=st.size(),cnt=0; if(mode==7)op=-1; for(int k=0; k<=3; k++){ //总共4个面,只取两个即可 if(ii[k]==2){ for(int j=3; j<=4; j++){ int i=ii[k]; int x=mp[i][j*3-3];int y=mp[i][j*3-2];int z=mp[i][j*3-1]; a[x][y][z][i] = st[(cnt+2*op+len)%len] ; cnt++; } continue; } for(int j=1; j<=2; j++){ int i=ii[k]; int x=mp[i][j*3-3];int y=mp[i][j*3-2];int z=mp[i][j*3-1]; a[x][y][z][i] = st[(cnt+2*op+len)%len] ;///y=2的四块,shun/ni时针 cnt++; } } } else if(mode==8||mode==9){ if(mode==9) op=-1; for(int j=3; j<=4; j++){ int i=1; int x=mp[i][j*3-3];int y=mp[i][j*3-2];int z=mp[i][j*3-1]; st.push_back(a[x][y][z][i]); } for(int j=2; j<=4; j+=2){ int i=5; int x=mp[i][j*3-3];int y=mp[i][j*3-2];int z=mp[i][j*3-1]; st.push_back(a[x][y][z][i]); } for(int j=1; j<=2; j++){ int i=3; int x=mp[i][j*3-3];int y=mp[i][j*3-2];int z=mp[i][j*3-1]; st.push_back(a[x][y][z][i]); } for(int j=1; j<=3; j+=2){ int i=4; int x=mp[i][j*3-3];int y=mp[i][j*3-2];int z=mp[i][j*3-1]; st.push_back(a[x][y][z][i]); } int len=st.size(),cnt=0; for(int j=3; j<=4; j++){ int i=1; int x=mp[i][j*3-3];int y=mp[i][j*3-2];int z=mp[i][j*3-1]; a[x][y][z][i] = st[(cnt-2*op+len)%len] ;///z=1的四块,shun/逆时针 cnt++; } for(int j=2; j<=4; j+=2){ int i=5; int x=mp[i][j*3-3];int y=mp[i][j*3-2];int z=mp[i][j*3-1]; a[x][y][z][i] = st[(cnt-2*op+len)%len] ;///z=1的四块,shun/逆时针 cnt++; } for(int j=1; j<=2; j++){ int i=3; int x=mp[i][j*3-3];int y=mp[i][j*3-2];int z=mp[i][j*3-1]; a[x][y][z][i] = st[(cnt-2*op+len)%len] ;///z=1的四块,shun/逆时针 cnt++; } for(int j=1; j<=3; j+=2){ int i=4; int x=mp[i][j*3-3];int y=mp[i][j*3-2];int z=mp[i][j*3-1]; a[x][y][z][i] = st[(cnt-2*op+len)%len] ;///z=1的四块,shun/逆时针 cnt++; } } else if(mode==10||mode==11){ if(mode==11)op=-1; for(int j=1; j<=2; j++){ int i=1; int x=mp[i][j*3-3];int y=mp[i][j*3-2];int z=mp[i][j*3-1]; st.push_back(a[x][y][z][i]); } for(int j=1; j<=3; j+=2){ int i=5; int x=mp[i][j*3-3];int y=mp[i][j*3-2];int z=mp[i][j*3-1]; st.push_back(a[x][y][z][i]); } for(int j=3; j<=4; j++){ int i=3; int x=mp[i][j*3-3];int y=mp[i][j*3-2];int z=mp[i][j*3-1]; st.push_back(a[x][y][z][i]); } for(int j=2; j<=4; j+=2){ int i=4; int x=mp[i][j*3-3];int y=mp[i][j*3-2];int z=mp[i][j*3-1]; st.push_back(a[x][y][z][i]); } int len=st.size(),cnt=0; for(int j=1; j<=2; j++){ int i=1; int x=mp[i][j*3-3];int y=mp[i][j*3-2];int z=mp[i][j*3-1]; a[x][y][z][i] = st[(cnt-2*op+len)%len] ;///z=2的四块,shun/逆时针 cnt++; } for(int j=1; j<=3; j+=2){ int i=5; int x=mp[i][j*3-3];int y=mp[i][j*3-2];int z=mp[i][j*3-1]; a[x][y][z][i] = st[(cnt-2*op+len)%len] ;///z=2的四块,shun/逆时针 cnt++; } for(int j=3; j<=4; j++){ int i=3; int x=mp[i][j*3-3];int y=mp[i][j*3-2];int z=mp[i][j*3-1]; a[x][y][z][i] = st[(cnt-2*op+len)%len] ;///z=2的四块,shun/逆时针 cnt++; } for(int j=2; j<=4; j+=2){ int i=4; int x=mp[i][j*3-3];int y=mp[i][j*3-2];int z=mp[i][j*3-1]; a[x][y][z][i] = st[(cnt-2*op+len)%len] ;///z=2的四块,shun/逆时针 cnt++; } } // debug(st,mode); } int main() { int T; scanf("%d",&T); while(T--) { for(int i=0; i<=5; i++) //总共六个面 { for(int j=1; j<=4; j++) { int x=mp[i][j*3-3]; int y=mp[i][j*3-2]; int z=mp[i][j*3-1]; cin>>a[x][y][z][i]; ///四维对应 x-y-z- face_id } } // vector<int>st; // debug(st,-1); if(judge()==true) { printf("我真是个小机灵鬼! "); } else { bool ans=false; for(int i=0;i<12&&!ans;i++) { rotating(i); ans=judge(); rotating(i^1); //旋转回去 } if(ans) printf("我真是个小机灵鬼! "); else printf("这个魔方有bug! "); } } return 0; } // for(int i=0;i<=11;i++){ // int test=i; // rotating(test);rotating(test^1);rotating(test^1);rotating(test); // ///test成功:0,1,2, 3,4,5,6,7,8,9 , // if(judge()==true) // { // printf("Test %d OK! ",test); // } // else{ // printf("%d False! ",test); // } // continue; // } //rotating(0);rotating(0^1); //测试成功 //rotating(2);rotating(3); ///测试成功 // rotating(4);rotating(4^1); ///测试成功 // rotating(6);rotating(6^1); ///测试成功 // rotating(10);rotating(10^1); ///测试成功 ,对一个正确的解,同一个层面顺拧一次、反拧一次必定正确 // rotating(2^1); // cout<<"^1= "<<(2^1)<<endl;