hduoj 3459 Rubik 2×2×2
http://acm.hdu.edu.cn/showproblem.php?pid=3459
Rubik 2×2×2
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 327670/327670 K (Java/Others)
Total Submission(s): 654 Accepted Submission(s): 234
Special Judge
Problem Description
Sonny is probably the only computer science Ph.D. student who cannot solve a Rubik's cube. One day, he came across a neat little 2×2×2 Rubik's cube, and thought, "Finally, here's a cube that's easy enough for me to do!" Nope, wrong! He got pwned, hardcore. How embarrassing.To ensure that this does not happen again, he decides to write a computer program to solve the cube. Then he had this brilliant idea: Why not have the students at the programming contest do the work instead? So, given an initial conguration of the 2×2×2 Rubik's cube, your task for this problem is to write a program that solves it. The mini-cube has 6 faces, each with 4 painted tiles on it. The faces are labeled Front (F), Back (B),Up (U), Down (D), Left (L), and Right (R), according to the diagram below. Each of the tiles on the faces can be colored Red (R), Green (G), Blue (B), Yellow (Y), Orange (O), or White (W), and there are exactly 4 instances of each color. The cube is considered solved when the colors of all tiles on each distinct face of the cube match. You may use any combination of three distinct moves to transform the cube: a turn about the X-axis,a turn about the Y-axis, or a turn about the Z-axis. Each turn is exactly 90 degrees of all tiles on half the cube, in the directions illustrated below. Note that the back-down-left corner is fixed with respect to all valid transforms. Can you come up with a sequence of moves that will solve a given conguration of the Rubik's cube?
Input
You will be given maps of an "unwrapped" cubes showing colors on each of the faces, in the following format: The letters in the above diagram shows you where to find the colors on each face (as shown in the first diagram) from the map only { it is not valid input! The front face is oriented as in the diagram, with the other faces on the map attached to it so that it wraps to cover the cube. The letters on the faces may be any of R, G, B, Y, O, or W to indicate the color. Dot (.) characters serve to pad the map to a 6 × 8 grid,and are of no other signicance.The input consists of several conguration maps in the format described, separated by blank lines. You may assume that each conguration is both valid and solvable. The end of input is denoted by an "empty" conguration consisting solely of `.' characters; do not process this map.
Output
For each cube, output on a single line a sequence of moves that will solve the cube. Output `X' for a turn about the X-axis, `Y' for a turn about the Y-axis, and `Z' for a turn about the Z-axis. Any sequence of moves (that is reasonably finite) which solves the given configuration will do. (After all, Sonny does need to execute your commands to verify that your program works!) A blank line will suffice for an input cube that is already solved.
Sample Input
..WO....
..WO....
BBOYGGWR
BBOYGGWR
..YR....
..YR....
..GY....
..BY....
ROYWRRBB
GWOWRBOW
..YG....
..OG....
........
........
........
........
........
........
Sample Output
X
YZXXXZYZXYXYZZYZZYZXYY
Source
分析:
题目不难理解,就是求还原的最小步数。
从图中不难看出,无论魔方怎么旋转,与原点相接的那个小方块是不动的,那么我们可以由原点的小方块得出三个面的最终颜色,然后再通过这三个面去确定其他三个面的颜色
然后就是IDA的剪枝估测函数的h值,由于每次旋转能够改变8个小面,那么只要求出现在不在其位的面总数SUM,得出(sum+7)/8即可,加7是保证sum+7>=8得出步数。
AC代码:
1 #include <stdio.h> 2 #include <string.h> 3 #include <algorithm> 4 using namespace std; 5 6 struct node 7 { 8 int x,y; 9 } cube[10][10],side[10][10]; 10 11 char color[10],rubik[10][10]; 12 int ans[1000]; 13 int flag,step; 14 15 void init()//cube代表每个小立方体的3个面对应字符数字的哪个位置,side则是6个面,每个面的四个元素分别是什么 16 { 17 cube[0][0].x=3,cube[0][0].y=2; 18 cube[0][1].x=3,cube[0][1].y=1; 19 cube[0][2].x=4,cube[0][2].y=2; 20 cube[1][0].x=3,cube[1][0].y=3; 21 cube[1][1].x=3,cube[1][1].y=4; 22 cube[1][2].x=4,cube[1][2].y=3; 23 cube[2][0].x=2,cube[2][0].y=2; 24 cube[2][1].x=2,cube[2][1].y=1; 25 cube[2][2].x=1,cube[2][2].y=2; 26 cube[3][0].x=2,cube[3][0].y=3; 27 cube[3][1].x=1,cube[3][1].y=3; 28 cube[3][2].x=2,cube[3][2].y=4; 29 cube[4][0].x=3,cube[4][0].y=0; 30 cube[4][1].x=5,cube[4][1].y=2; 31 cube[4][2].x=3,cube[4][2].y=7; 32 cube[5][0].x=5,cube[5][0].y=3; 33 cube[5][1].x=3,cube[5][1].y=5; 34 cube[5][2].x=3,cube[5][2].y=6; 35 cube[6][0].x=0,cube[6][0].y=2; 36 cube[6][1].x=2,cube[6][1].y=7; 37 cube[6][2].x=2,cube[6][2].y=0; 38 cube[7][0].x=0,cube[7][0].y=3; 39 cube[7][1].x=2,cube[7][1].y=5; 40 cube[7][2].x=2,cube[7][2].y=6; 41 side[0][0].x=0,side[0][0].y=2; 42 side[0][1].x=0,side[0][1].y=3; 43 side[0][2].x=1,side[0][2].y=2; 44 side[0][3].x=1,side[0][3].y=3; 45 side[1][0].x=2,side[1][0].y=0; 46 side[1][1].x=2,side[1][1].y=1; 47 side[1][2].x=3,side[1][2].y=0; 48 side[1][3].x=3,side[1][3].y=1; 49 side[2][0].x=2,side[2][0].y=2; 50 side[2][1].x=2,side[2][1].y=3; 51 side[2][2].x=3,side[2][2].y=2; 52 side[2][3].x=3,side[2][3].y=3; 53 side[3][0].x=2,side[3][0].y=4; 54 side[3][1].x=2,side[3][1].y=5; 55 side[3][2].x=3,side[3][2].y=4; 56 side[3][3].x=3,side[3][3].y=5; 57 side[4][0].x=2,side[4][0].y=6; 58 side[4][1].x=2,side[4][1].y=7; 59 side[4][2].x=3,side[4][2].y=6; 60 side[4][3].x=3,side[4][3].y=7; 61 side[5][0].x=4,side[5][0].y=2; 62 side[5][1].x=4,side[5][1].y=3; 63 side[5][2].x=5,side[5][2].y=2; 64 side[5][3].x=5,side[5][3].y=3; 65 } 66 67 char get_color(int A,int B,int C) //通过小格子的颜色获得每个面的颜色 68 { 69 for(int i=0; i<8; i++) 70 { 71 if(rubik[cube[i][0].x][cube[i][0].y]==color[A]&&rubik[cube[i][1].x][cube[i][1].y]==color[B]&&rubik[cube[i][2].x][cube[i][2].y]!=color[C]) 72 return rubik[cube[i][2].x][cube[i][2].y]; 73 if(rubik[cube[i][1].x][cube[i][1].y]==color[A]&&rubik[cube[i][0].x][cube[i][0].y]==color[B]&&rubik[cube[i][2].x][cube[i][2].y]!=color[C]) 74 return rubik[cube[i][2].x][cube[i][2].y]; 75 if(rubik[cube[i][0].x][cube[i][0].y]==color[A]&&rubik[cube[i][2].x][cube[i][2].y]==color[B]&&rubik[cube[i][1].x][cube[i][1].y]!=color[C]) 76 return rubik[cube[i][1].x][cube[i][1].y]; 77 if(rubik[cube[i][2].x][cube[i][2].y]==color[A]&&rubik[cube[i][0].x][cube[i][0].y]==color[B]&&rubik[cube[i][1].x][cube[i][1].y]!=color[C]) 78 return rubik[cube[i][1].x][cube[i][1].y]; 79 if(rubik[cube[i][1].x][cube[i][1].y]==color[A]&&rubik[cube[i][2].x][cube[i][2].y]==color[B]&&rubik[cube[i][0].x][cube[i][0].y]!=color[C]) 80 return rubik[cube[i][0].x][cube[i][0].y]; 81 if(rubik[cube[i][2].x][cube[i][2].y]==color[A]&&rubik[cube[i][1].x][cube[i][1].y]==color[B]&&rubik[cube[i][0].x][cube[i][0].y]!=color[C]) 82 return rubik[cube[i][0].x][cube[i][0].y]; 83 } 84 } 85 86 void turn_x(char maze[10][10]) //x轴 87 { 88 char tmp; 89 tmp=maze[2][4]; 90 maze[2][4]=maze[2][5]; 91 maze[2][5]=maze[3][5]; 92 maze[3][5]=maze[3][4]; 93 maze[3][4]=tmp; 94 tmp=maze[1][3]; 95 maze[1][3]=maze[2][6]; 96 maze[2][6]=maze[5][3]; 97 maze[5][3]=maze[3][3]; 98 maze[3][3]=tmp; 99 tmp=maze[0][3]; 100 maze[0][3]=maze[3][6]; 101 maze[3][6]=maze[4][3]; 102 maze[4][3]=maze[2][3]; 103 maze[2][3]=tmp; 104 } 105 void turn_y(char maze[10][10]) //y轴 106 { 107 char tmp; 108 tmp=maze[2][0]; 109 maze[2][0]=maze[2][6]; 110 maze[2][6]=maze[2][4]; 111 maze[2][4]=maze[2][2]; 112 maze[2][2]=tmp; 113 tmp=maze[2][1]; 114 maze[2][1]=maze[2][7]; 115 maze[2][7]=maze[2][5]; 116 maze[2][5]=maze[2][3]; 117 maze[2][3]=tmp; 118 tmp=maze[0][2]; 119 maze[0][2]=maze[0][3]; 120 maze[0][3]=maze[1][3]; 121 maze[1][3]=maze[1][2]; 122 maze[1][2]=tmp; 123 } 124 void turn_z(char maze[10][10]) //z轴 125 { 126 char tmp; 127 tmp=maze[2][1]; 128 maze[2][1]=maze[1][3]; 129 maze[1][3]=maze[3][4]; 130 maze[3][4]=maze[4][2]; 131 maze[4][2]=tmp; 132 tmp=maze[3][1]; 133 maze[3][1]=maze[1][2]; 134 maze[1][2]=maze[2][4]; 135 maze[2][4]=maze[4][3]; 136 maze[4][3]=tmp; 137 tmp=maze[2][2]; 138 maze[2][2]=maze[2][3]; 139 maze[2][3]=maze[3][3]; 140 maze[3][3]=maze[3][2]; 141 maze[3][2]=tmp; 142 } 143 144 int get_h(char mid[10][10]) 145 { 146 int i,j,sum = 0; 147 for(i = 0; i<6; i++) 148 { 149 for(j = 0; j<4; j++) 150 { 151 if(mid[side[i][j].x][side[i][j].y]!=color[i]) 152 sum++; 153 } 154 } 155 return (sum+7)/8; 156 } 157 158 int IDA(char mid[10][10],int cnt) 159 { 160 if(cnt+get_h(mid)>step) 161 return 0; 162 if(cnt == step) 163 return 1; 164 for(int i = 0; i<3; i++) 165 { 166 char tem[10][10]; 167 for(int x = 0; x<6; x++) 168 for(int y = 0; y<8; y++) 169 tem[x][y]=mid[x][y]; 170 if(i == 0) 171 turn_x(tem); 172 else if(i == 1) 173 turn_y(tem); 174 else 175 turn_z(tem); 176 ans[cnt] = i; 177 if(IDA(tem,cnt+1)) 178 return 1; 179 } 180 return 0; 181 } 182 int main() 183 { 184 int i; 185 init(); 186 while(~scanf("%s",rubik[0])) 187 { 188 for(i = 1; i<6; i++) 189 scanf("%s",rubik[i]); 190 if(!strcmp(rubik[0],"........")) 191 break; 192 color[1]=rubik[3][0]; 193 color[5]=rubik[5][2]; 194 color[4]=rubik[3][7]; 195 color[0]=get_color(1,4,5); 196 color[2]=get_color(1,5,4); 197 color[3]=get_color(4,5,1); 198 step = 0; 199 while(1) 200 { 201 if(IDA(rubik,0)) break; 202 step++; 203 } 204 for(i = 0; i<step; i++) 205 printf("%c",ans[i]+'X'); 206 printf("\n"); 207 } 208 209 return 0; 210 }
悠游天地间 all rights reserved. © 2013 -- 1 << 64