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暴力1150ms卡过,正解是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 */

加上估价函数, 试了一下IDA*,跑的果然快,20ms,快了50倍。

  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     int h() {
117         int res = 0;
118         for (int i = 0; i < 6; ++i) {
119             set<char> ss;
120             for (int j = 1; j <= 9; ++j) {
121                 ss.insert(a[i][j]);
122             }
123             int siz = ss.size();
124             if (res < siz) res = siz;
125         }
126         return res;
127     }
128 };
129 int T;
130 cube a;
131 void get_a() {
132     vector<char> vec;
133     char c;
134     while (vec.size() < 54) {
135         c = getchar();
136         if (isalpha(c)) {
137             vec.pb(c);
138         }
139     }
140     for (int i = 0; i < 9; ++i) {
141         a.a[4][i + 1] = vec[i];
142     }
143     for (int l = 0; l < 3; ++l) {
144         for (int f = 0; f < 4; ++f) {
145             for (int i = 1; i <= 3; ++i) {
146                 a.a[f][l * 3 + i] = vec[l * 12 + f * 3 + i + 8];
147             }
148         }
149     }
150     for (int i = 1; i <= 9; ++i) {
151         a.a[5][i] = vec[44 + i];
152     }
153     int dir[8] = {1, 2, 3, 6, 9, 8, 7, 4};
154     int x = a.a[4][dir[7]], y = a.a[4][dir[6]];
155     for (int i = 7; i > 2; i -= 2) {
156         a.a[4][dir[i]] = a.a[4][dir[i - 2]];
157         a.a[4][dir[i - 1]] = a.a[4][dir[i - 3]];
158     }
159     a.a[4][dir[1]] = x;
160     a.a[4][dir[0]] = y;
161     x = a.a[5][dir[0]];
162     y = a.a[5][dir[1]];
163     for (int i = 0; i < 5; i += 2) {
164         a.a[5][dir[i]] = a.a[5][dir[i + 2]];
165         a.a[5][dir[i + 1]] = a.a[5][dir[i + 3]];
166     }
167     a.a[5][dir[7]] = y;
168     a.a[5][dir[6]] = x;
169     /*for (int i = 0; i < 6; ++i) {
170         for (int j = 1; j <= 9; ++j) {
171             cout << a.a[i][j] << ' ';
172         }
173         cout << endl;
174     }*/
175 }
176 queue<pcv> que;
177 int main() {
178     scanf("%d", &T);
179     while (T--) {
180         get_a();
181         while (que.size()) {
182             que.pop();
183         }
184         vector<pii> vec, ans;
185         que.push(mp(a, vec));
186         int flag = 0;
187         while (que.size()) {
188             pcv pp = que.front(); que.pop();
189             cube a = pp.first;
190             vector<pii> vec = pp.second;
191             if (a.ok()) {
192                 ans = vec;
193                 flag = 1;
194                 break;
195             }
196             if (a.h() + vec.size() > 6) continue;
197             if (5 == vec.size()) continue;
198             for (int f = 0; f < 6; ++f) {
199                 cube b1 = a.clockwise(f);
200                 //printf("%d\n", f); pau;
201                 vector<pii> vec1 = vec;
202                 vec1.pb(mp(f, 1));
203                 que.push(mp(b1, vec1));
204                 cube b2 = b1.clockwise(f).clockwise(f);
205                 vector<pii> vec2 = vec;
206                 vec2.pb(mp(f, -1));
207                 que.push(mp(b2, vec2));
208             }
209         }
210         if (flag) {
211             printf("%d\n", ans.size());
212             for (int i = 0; i < ans.size(); ++i) {
213                 int x = ans[i].first, y = ans[i].second;
214                 printf("%d %d\n", x, y);
215             }
216         } else {
217             puts("-1");
218         }
219     }
220     return 0;
221 }
222 /*
223 3
224       w w w
225       w w w
226       w w w
227 r r r g g g b b b o o o
228 r r r g g g b b b o o o
229 r r r g g g b b b o o o
230       y y y
231       y y y
232       y y y
233 
234       w w w
235       w w w
236       b b b
237 r r w g g g y b b o o o
238 r r w g g g y b b o o o
239 r r w g g g y b b o o o
240       r r r
241       y y y
242       y y y
243 */

 

转载于:https://www.cnblogs.com/BIGTOM/p/8493402.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值