ZOJ - 2477 Magic Cube 题解

Posted hit_yjl

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ZOJ - 2477 Magic Cube 题解相关的知识,希望对你有一定的参考价值。

This is a very popular game for children. In this game, there‘s a cube, which consists of 3 * 3 * 3 small cubes. We can unwrap the cube, it will become like this:

      w w w
      w w w
      w w w
r r r g g g b b b o o o
r r r g g g b b b o o o
r r r g g g b b b o o o
      y y y
      y y y
      y y y

The letters means the color on the small cubes. For example, ‘r‘ means red, ‘g‘ means green, ‘y‘ means yellow....The goal for this game is to rotate the faces of the cube to make each of the faces contains only one color. Note there‘re exact 6 kind of colors on the cube and there‘re exact 9 small rectangles totally in any time in the game.

Do you know how to rotate the faces? I think most of you have known it. But I would like to show it again. When a face is rotated, the configuration of colors in all the adjacent faces changes. For the cube above, after we rotate the green face clock-wise, the last line of ‘w‘ face will become the left column of ‘b‘ face, the left column of ‘b‘ face will become the top line of ‘y‘ face, etc. As you may know, reaching the final position from a scrambled configuration can be quite challenging.

In this problem, you are given a configuration of the cube, and asked to give a way to reach the final position. To reduce the difficulty, the steps required will never be greater than 5.


Input

The input contains an integer in the first line, which indicates the number of the test cases. In each test case, there‘re exact 10 lines. The first line is an empty line. The next 9 lines contain a configuration. The format can be seen in the sample input. For simplicity, we give an index to each face as follows:

 

    /---\
    |   |
    | 4 |
    |   |
/---+---+---+---\
|   |   |   |   |
| 0 | 1 | 2 | 3 |
|   |   |   |   |
\---+---+---+---/
    |   |
    | 5 |
    |   |
    \---/

Note that there‘s a space between two adjacent letters.


Output

For each test case, the first line of the output is the smallest count N of the steps to reach the winning position. If the winning position can‘t be reached in 5 steps, print -1 in this line. Otherwise print each step in one line in the following N lines. A step contains two integers, the first one means the face index, and the second one means the direction. 1 means clock-wise and -1 means counter clock-wise. If the given position is the winning position, print 0 for such test case simply. If there‘re multiple solutions, any one is acceptable.


Sample Input

2
      w w w
      w w w
      w w w
r r r g g g b b b o o o
r r r g g g b b b o o o
r r r g g g b b b o o o
      y y y
      y y y
      y y y

      w w w
      w w w
      b b b
r r w g g g y b b o o o
r r w g g g y b b o o o
r r w g g g y b b o o o
      r r r
      y y y
      y y y


Sample Output

0
1
1 1

 

题意:还原一个魔方,如果超过5步,输出-1即可,否则输出最快还原步骤。

思路:题意说的不清楚,需要对着样例转一下4面和5面。一顿模拟就好了,想法很简单,但要维护旋转时位置的更替关系,写起来还是比较恶心的,,,用bfs暴力卡过,正解是IDA*,可以用所有面中不合法的颜色种类数作为估价函数。

  1 #include <iostream>
  2 #include <fstream>
  3 #include <sstream>
  4 #include <cstdlib>
  5 #include <cstdio>
  6 #include <cmath>
  7 #include <string>
  8 #include <cstring>
  9 #include <algorithm>
 10 #include <queue>
 11 #include <stack>
 12 #include <vector>
 13 #include <set>
 14 #include <map>
 15 #include <list>
 16 #include <iomanip>
 17 #include <cctype>
 18 #include <cassert>
 19 #include <bitset>
 20 #include <ctime>
 21 
 22 using namespace std;
 23 
 24 #define pau system("pause")
 25 #define ll long long
 26 #define pii pair<int, int>
 27 #define pb push_back
 28 #define mp make_pair
 29 #define clr(a, x) memset(a, x, sizeof(a))
 30 #define pcv pair<cube, vector<pii> >
 31 
 32 const double pi = acos(-1.0);
 33 const int INF = 0x3f3f3f3f;
 34 const int MOD = 1e9 + 7;
 35 const double EPS = 1e-9;
 36 
 37 struct cube {
 38     char a[6][11];
 39     cube rot(int face[], int p[][3]) {
 40         cube b;
 41         for (int i = 0; i < 6; ++i) {
 42             for (int j = 1; j <= 9; ++j) {
 43                 b.a[i][j] = a[i][j];
 44             }
 45         }
 46         for (int i = 0; i < 4; ++i) {
 47             int _i = (i + 3) % 4;
 48             int f = face[i], _f = face[_i];
 49             //cout << f << ‘ ‘ << _f << endl;
 50             for (int j = 0; j < 3; ++j) {
 51                 b.a[f][p[i][j]] = a[_f][p[_i][j]];
 52             }
 53         }
 54         return b;
 55     }
 56     cube clockwise(int face) {
 57         cube b;
 58         int f[4], p[4][3];
 59         if (!face) {
 60             f[0] = 4, f[1] = 1, f[2] = 5, f[3] = 3;
 61             p[0][0] = 1, p[0][1] = 2, p[0][2] = 3;
 62             p[1][0] = 7, p[1][1] = 4, p[1][2] = 1;
 63             p[2][0] = 9, p[2][1] = 8, p[2][2] = 7;
 64             p[3][0] = 3, p[3][1] = 6, p[3][2] = 9;
 65         } else if (1 == face) {
 66             f[0] = 4, f[1] = 2, f[2] = 5, f[3] = 0;
 67             p[0][0] = 1, p[0][1] = 4, p[0][2] = 7;
 68             p[1][0] = 1, p[1][1] = 4, p[1][2] = 7;
 69             p[2][0] = 1, p[2][1] = 4, p[2][2] = 7;
 70             p[3][0] = 9, p[3][1] = 6, p[3][2] = 3;
 71         } else if (2 == face) {
 72             f[0] = 4, f[1] = 3, f[2] = 5, f[3] = 1;
 73             p[0][0] = 7, p[0][1] = 8, p[0][2] = 9;
 74             p[1][0] = 1, p[1][1] = 4, p[1][2] = 7;
 75             p[2][0] = 3, p[2][1] = 2, p[2][2] = 1;
 76             p[3][0] = 9, p[3][1] = 6, p[3][2] = 3;
 77         } else if (3 == face) {
 78             f[0] = 4, f[1] = 0, f[2] = 5, f[3] = 2;
 79             p[0][0] = 9, p[0][1] = 6, p[0][2] = 3;
 80             p[1][0] = 1, p[1][1] = 4, p[1][2] = 7;
 81             p[2][0] = 9, p[2][1] = 6, p[2][2] = 3;
 82             p[3][0] = 9, p[3][1] = 6, p[3][2] = 3;
 83         } else if (4 == face) {
 84             f[0] = 0, f[1] = 3, f[2] = 2, f[3] = 1;
 85             for (int i = 0; i < 4; ++i) {
 86                 p[i][0] = 3, p[i][1] = 2, p[i][2] = 1;
 87             }
 88         } else {
 89             f[0] = 2, f[1] = 3, f[2] = 0, f[3] = 1;
 90             for (int i = 0; i < 4; ++i) {
 91                 p[i][0] = 7, p[i][1] = 8, p[i][2] = 9;
 92             }
 93         }
 94         b = rot(f, p);
 95         b.a[face][1] = a[face][7];
 96         b.a[face][2] = a[face][4];
 97         b.a[face][3] = a[face][1];
 98         b.a[face][4] = a[face][8];
 99         b.a[face][6] = a[face][2];
100         b.a[face][7] = a[face][9];
101         b.a[face][8] = a[face][6];
102         b.a[face][9] = a[face][3];
103         return b;
104     }
105     bool ok() {
106         for (int i = 0; i < 6; ++i) {
107             char c = a[i][1];
108             for (int j = 2; j <= 9; ++j) {
109                 if (c != a[i][j]) {
110                     return false;
111                 }
112             }
113         }
114         return true;
115     }
116 };
117 int T;
118 cube a;
119 void get_a() {
120     vector<char> vec;
121     char c;
122     while (vec.size() < 54) {
123         c = getchar();
124         if (isalpha(c)) {
125             vec.pb(c);
126         }
127     }
128     for (int i = 0; i < 9; ++i) {
129         a.a[4][i + 1] = vec[i];
130     }
131     for (int l = 0; l < 3; ++l) {
132         for (int f = 0; f < 4; ++f) {
133             for (int i = 1; i <= 3; ++i) {
134                 a.a[f][l * 3 + i] = vec[l * 12 + f * 3 + i + 8];
135             }
136         }
137     }
138     for (int i = 1; i <= 9; ++i) {
139         a.a[5][i] = vec[44 + i];
140     }
141     int dir[8] = {1, 2, 3, 6, 9, 8, 7, 4};
142     int x = a.a[4][dir[7]], y = a.a[4][dir[6]];
143     for (int i = 7; i > 2; i -= 2) {
144         a.a[4][dir[i]] = a.a[4][dir[i - 2]];
145         a.a[4][dir[i - 1]] = a.a[4][dir[i - 3]];
146     }
147     a.a[4][dir[1]] = x;
148     a.a[4][dir[0]] = y;
149     x = a.a[5][dir[0]];
150     y = a.a[5][dir[1]];
151     for (int i = 0; i < 5; i += 2) {
152         a.a[5][dir[i]] = a.a[5][dir[i + 2]];
153         a.a[5][dir[i + 1]] = a.a[5][dir[i + 3]];
154     }
155     a.a[5][dir[7]] = y;
156     a.a[5][dir[6]] = x;
157     /*for (int i = 0; i < 6; ++i) {
158         for (int j = 1; j <= 9; ++j) {
159             cout << a.a[i][j] << ‘ ‘;
160         }
161         cout << endl;
162     }*/
163 }
164 queue<pcv> que;
165 int main() {
166     scanf("%d", &T);
167     while (T--) {
168         get_a();
169         while (que.size()) {
170             que.pop();
171         }
172         vector<pii> vec, ans;
173         que.push(mp(a, vec));
174         int flag = 0;
175         while (que.size()) {
176             pcv pp = que.front(); que.pop();
177             cube a = pp.first;
178             vector<pii> vec = pp.second;
179             if (a.ok()) {
180                 ans = vec;
181                 flag = 1;
182                 break;
183             }
184             if (5 == vec.size()) continue;
185             for (int f = 0; f < 6; ++f) {
186                 cube b1 = a.clockwise(f);
187                 //printf("%d\n", f); pau;
188                 vector<pii> vec1 = vec;
189                 vec1.pb(mp(f, 1));
190                 que.push(mp(b1, vec1));
191                 cube b2 = b1.clockwise(f).clockwise(f);
192                 vector<pii> vec2 = vec;
193                 vec2.pb(mp(f, -1));
194                 que.push(mp(b2, vec2));
195             }
196         }
197         if (flag) {
198             printf("%d\n", ans.size());
199             for (int i = 0; i < ans.size(); ++i) {
200                 int x = ans[i].first, y = ans[i].second;
201                 printf("%d %d\n", x, y);
202             }
203         } else {
204             puts("-1");
205         }
206     }
207     return 0;
208 }
209 /*
210 3
211       w w w
212       w w w
213       w w w
214 r r r g g g b b b o o o
215 r r r g g g b b b o o o
216 r r r g g g b b b o o o
217       y y y
218       y y y
219       y y y
220 
221       w w w
222       w w w
223       b b b
224 r r w g g g y b b o o o
225 r r w g g g y b b o o o
226 r r w g g g y b b o o o
227       r r r
228       y y y
229       y y y
230 */

 

以上是关于ZOJ - 2477 Magic Cube 题解的主要内容,如果未能解决你的问题,请参考以下文章

ZOJ2477 Magic Cube

ACM-ICPC 2018 青岛赛区现场赛 D. Magic Multiplication && ZOJ 4061 (思维+构造)

题解 ZOJ3203 Light Bulb

ZOJ3662:Math Magic(全然背包)

ZOJ - 3662 Math Magic(dp)

ZOJ 3622 Magic Number(数)