sdutoj 2606 Rubik’s cube
http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2606
Rubik’s cube
Time Limit: 2000ms Memory limit: 65536K 有疑问?点这里^_^
题目描述
Flabby is addicted to Rubik’s cube. He has many kinds of Rubik’s cube and plays them well. He can reorder a Rubik’s cube in a few seconds. He is famous for playing Rubik’s cube and attracts many young girls. One of his friends, Ant, is jealous of him and decides to let him be embarrassed in public. Ant makes a small Rubik’s cube by himself. This small magic is 2*2*2 and is drawn in blue and red, as shown in Figure 1.
This Rubik’s cube can be rotated as well as other kinds of magic cube. Each of six faces can rotated clockwise and counterclockwise. Each 90 degree rotation on any face is counted as one step. The Rubik’s cube which has been reordered has only one color on each face.
Ant is a clever boy. Sometimes, he can make a Rubik’s cube which can be reordered in a few steps. He can also make a Rubik’s cube which can’t be reordered in any way.
Flabby knows what Ant thinks in his mind. He knows that you are a good programmer and asks you for help. Tell him whether this special Rubik’s cube can be reordered in a few steps.
This Rubik’s cube can be rotated as well as other kinds of magic cube. Each of six faces can rotated clockwise and counterclockwise. Each 90 degree rotation on any face is counted as one step. The Rubik’s cube which has been reordered has only one color on each face.
Ant is a clever boy. Sometimes, he can make a Rubik’s cube which can be reordered in a few steps. He can also make a Rubik’s cube which can’t be reordered in any way.
Flabby knows what Ant thinks in his mind. He knows that you are a good programmer and asks you for help. Tell him whether this special Rubik’s cube can be reordered in a few steps.
输入
In the input file, the first line is an integer T which is the number of test case. For each test case, there is 6 lines of integers describe the Rubik’s cube. For each line, there are four integers. Pij which is shown in Figure 3 corresponds to the jth integer of the ith line. If Pij is 0, it means the corresponding place is red. If Pij is 1, it means the corresponding place is blue.
输出
If the magic cube can be reordered in n steps, output the minimum n in a line. If the magic cube cannot be reordered, output “IMPOSSIBLE!” in a line.
示例输入
3 0 0 0 0 0 1 0 1 1 1 0 0 1 0 1 0 1 1 0 0 1 1 1 1 0 0 1 1 1 1 0 0 0 1 0 1 1 0 0 0 1 1 1 1 0 1 0 0 1 0 1 1 0 1 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 1 1 1
示例输出
1 IMPOSSIBLE! 8
提示
来源
2013年山东省第四届ACM大学生程序设计竞赛
示例程序
官方代码:
1 /** 2 23 3 10 4 23 5 10 6 010101 7 323232 8 01 9 32 10 6 11 3 12 412 13 5 14 */ 15 #include <iostream> 16 #include <cstring> 17 #include <cstdio> 18 #include <cstdlib> 19 using namespace std; 20 char md[6][4]; 21 #define MAX 20000000 22 bool flag[16][16][16][16][16][16]; 23 struct M 24 { 25 short int num[6]; 26 short int lv; 27 void print() 28 { 29 int i; 30 for(i = 0; i < 6; i++) 31 printf("%d ",num[i]); 32 printf("\n"); 33 return; 34 } 35 }queue[MAX]; 36 M (*funp[6])(M m); 37 bool check(M m) 38 { 39 int i; 40 for(i = 0; i < 6; i++) 41 { 42 if(m.num[i] != 15 && m.num[i] != 0) 43 return false; 44 } 45 return true; 46 } 47 M turnY_L(M tm) 48 { 49 M m; 50 m.num[0] = (tm.num[0] >> 1) | ((tm.num[0] & 1) << 3); 51 m.num[1] = (tm.num[1] & 6) | ((tm.num[4] & 1) << 3) | ((tm.num[4] & 2) >> 1); 52 m.num[2] = (tm.num[2] & 12) | ((tm.num[1] & 1) << 1) | ((tm.num[1] & 8) >> 3); 53 m.num[3] = (tm.num[3] & 9) | ((tm.num[2] & 2) << 1) | ((tm.num[2] & 1) << 1); 54 m.num[4] = (tm.num[4] & 12) | ((tm.num[3] & 4) >> 1) | ((tm.num[3] & 2) >> 1); 55 m.num[5] = tm.num[5]; 56 return m; 57 } 58 M turnY_R(M tm) 59 { 60 M m; 61 m.num[0] = ((tm.num[0] & 7) << 1) | ((tm.num[0] & 8) >> 3); 62 m.num[1] = (tm.num[1] & 6) | ((tm.num[2] & 2) >> 1) | ((tm.num[2] & 1) << 3); 63 m.num[2] = (tm.num[2] & 12) | ((tm.num[3] & 4) >> 1) | ((tm.num[3] & 2) >> 1); 64 m.num[3] = (tm.num[3] & 9) | ((tm.num[4] & 1) << 1) | ((tm.num[4] & 2) << 1); 65 m.num[4] = (tm.num[4] & 12) | ((tm.num[1] & 1) << 1) | ((tm.num[1] & 8) >> 3); 66 m.num[5] = tm.num[5]; 67 return m; 68 } 69 70 /*------------------------------------------------------------------------------------*/ 71 72 M turnX_L(M tm) 73 { 74 M m; 75 m.num[1] = (tm.num[1] >> 1) | ((tm.num[1] & 1) << 3); 76 m.num[0] = (tm.num[0] & 9) | ((tm.num[2] & 1) << 2) | ((tm.num[2] & 8) >> 2); 77 m.num[2] = (tm.num[2] & 6) | ((tm.num[5] & 9)); 78 m.num[3] = tm.num[3]; 79 m.num[4] = (tm.num[4] & 9) | ((tm.num[0] & 6)); 80 m.num[5] = (tm.num[5] & 6) | ((tm.num[4] & 4) >> 2) | ((tm.num[4] & 2) << 2); 81 return m; 82 } 83 M turnX_R(M tm) 84 { 85 M m; 86 m.num[1] = ((tm.num[1] & 7) << 1) | ((tm.num[1] & 8) >> 3); 87 m.num[0] = (tm.num[0] & 9) | ((tm.num[4] & 6)); 88 m.num[2] = (tm.num[2] & 6) | ((tm.num[0] & 4) >> 2) | ((tm.num[0] & 2) << 2); 89 m.num[3] = tm.num[3]; 90 m.num[4] = (tm.num[4] & 9) | ((tm.num[5] & 8) >> 2) | ((tm.num[5] & 1) << 2); 91 m.num[5] = (tm.num[5] & 6) | ((tm.num[2] & 9)); 92 return m; 93 } 94 95 M turnZ_L(M tm) 96 { 97 M m; 98 m.num[4] = (tm.num[4] >> 1) | ((tm.num[4] & 1) << 3); 99 m.num[0] = (tm.num[0] & 3) | (tm.num[1] & 12); 100 m.num[1] = (tm.num[1] & 3) | (tm.num[5] & 12); 101 m.num[2] = tm.num[2]; 102 m.num[3] = (tm.num[3] & 3) | (tm.num[0] & 12); 103 m.num[5] = (tm.num[5] & 3) | (tm.num[3] & 12); 104 return m; 105 } 106 M turnZ_R(M tm) 107 { 108 M m; 109 m.num[4] = ((tm.num[4] & 7)<< 1) | ((tm.num[4] & 8) >> 3); 110 m.num[0] = (tm.num[0] & 3) | (tm.num[3] & 12); 111 m.num[1] = (tm.num[1] & 3) | (tm.num[0] & 12); 112 m.num[2] = tm.num[2]; 113 m.num[3] = (tm.num[3] & 3) | (tm.num[5] & 12); 114 m.num[5] = (tm.num[5] & 3) | (tm.num[1] & 12); 115 return m; 116 } 117 118 119 void record_flag(int num1,int num2,int num3,int num4,int num5,int num6) 120 { 121 //printf("%d %d %d %d %d %d\n",num1,num2,num3,num4,num5,num6); 122 flag[num1][num2][num3][num4][num5][num6] = 1; 123 flag[num4][num1][(num3>>1)|((num3&1)<<3)][num6][((num5&7)<<1)+((num3&8)>>3)][num2] = 1; 124 flag[num6][num4][((num3&3)<<2)+((num3&12)>>2)][num2][((num5&3)<<2)+((num5&12)>>2)][num1] = 1; 125 flag[num2][num6][((num3&7)<<1)|((num3&8)>>3)][num1][(num5>>1)+((num5&1)<<3)][num4] = 1; 126 return; 127 } 128 int Search(M m) 129 { 130 funp[0] = turnX_L; 131 funp[1] = turnX_R; 132 funp[2] = turnY_L; 133 funp[3] = turnY_R; 134 funp[4] = turnZ_L; 135 funp[5] = turnZ_R; 136 M tmp,tm; 137 int front,rear,i; 138 front = rear = 0; 139 memset(flag,0,sizeof(flag)); 140 m.lv = 0; 141 queue[rear++] = m; 142 record_flag(m.num[0],m.num[1],m.num[2],m.num[3],m.num[4],m.num[5]); 143 while(front < rear) 144 { 145 tmp = queue[front++]; 146 if(check(tmp)) 147 return tmp.lv; 148 for(i = 0; i < 6; i++) 149 { 150 tm = funp[i](tmp); 151 tm.lv = tmp.lv + 1; 152 if(flag[tm.num[0]][tm.num[1]][tm.num[2]][tm.num[3]][tm.num[4]][tm.num[5]] == 0) 153 { 154 queue[rear++] = tm; 155 record_flag(tm.num[0],tm.num[1],tm.num[2],tm.num[3],tm.num[4],tm.num[5]); 156 } 157 } 158 } 159 return -1; 160 } 161 162 int main() 163 { 164 int T,i,n1,n2,n3,n4,ans; 165 freopen("data.in","r",stdin); 166 freopen("data.out","w",stdout); 167 scanf("%d",&T); 168 M m; 169 while(T--) 170 { 171 for(i = 0; i < 6; i++) 172 { 173 scanf("%d%d%d%d",&n1,&n2,&n3,&n4); 174 m.num[i] = n1 + (n2 << 1) + (n3 << 3) + (n4 << 2); 175 // printf("%d\n",m.num[i]); 176 } 177 ans = Search(m); 178 if(ans != -1) 179 printf("%d\n", ans); 180 else 181 printf("IMPOSSIBLE!\n"); 182 } 183 return 0; 184 }
官方数据生成代码:
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <ctime> 5 #include <cstdlib> 6 using namespace std; 7 int a[24] = {0,0,1,1,1,1,0,0,0,1,0,1,1,0,1,0,1,1,0,1,0,1,0,0}; 8 int main() 9 { 10 int t1,t2,i; 11 freopen("data.in","w",stdout); 12 int T = 10; 13 printf("%d\n",T); 14 srand(0); 15 while(T--) 16 { 17 18 t1 = rand()%24; 19 do 20 { 21 t2 = ((rand()%24)*(rand()%24))%24; 22 }while(a[t1]==a[t2]); 23 a[t1] = a[t1] ^ a[t2]; 24 a[t2] = a[t1] ^ a[t2]; 25 a[t1] = a[t1] ^ a[t2]; 26 for(i = 0; i < 24; i++) 27 { 28 printf("%d",a[i]); 29 if(i % 4 == 3) 30 printf("\n"); 31 else 32 printf(" "); 33 } 34 printf("\n"); 35 } 36 return 0; 37 }
悠游天地间 all rights reserved. © 2013 -- 1 << 64