ZOJ 2477 Magic Cube(魔方)

ZOJ 2477 Magic Cube(魔方)ide

Time Limit: 2 Seconds      Memory Limit: 65536 KB測試

  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:ui

這是個有名的兒童遊戲。遊戲中有個方塊,由3*3*3的小方塊組成。咱們能夠把方塊展開以下:
CN

 

      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.this

 

  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.spa

 

  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.code

這些小寫字母表示小方塊的顏色。好比,’r’爲紅,’g’爲綠,’y’爲黃...遊戲目標爲經過旋轉某面方塊使得每面只有一種顏色。注意,方塊上僅有6種顏色,而且在遊戲的任意時刻都有9個準確的矩形。

你知道如何旋轉否?我想大部分人都懂,然而仍是要講一講。某面旋轉後,將改變全部相鄰面的顏色。如上述立方體,順時針旋轉綠色面後,’w’面的最後一行將變成’b’面的左列,’b’面的左列將變成’y’面的頂行,以此類推。你或許知道從亂序變爲最終狀態是至關有挑戰性的。

此問題中,給定一個方塊,要求尋找一種到達最終狀態的方法。爲了下降難度,必須步驟數不超過5。
CN

 

Input - 輸入orm

  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:blog

輸入的第一行爲一個整數,表示測試用例的數量。每一個測試用例10行。
第一行爲空行。隨後9行爲魔方配置。格式參照輸入樣例。簡單起見,每面索引以下:
CN
    /---\
    |   |
    | 4 |
    |   |
/---+---+---+---\
|   |   |   |   |
| 0 | 1 | 2 | 3 |
|   |   |   |   |
\---+---+---+---/
    |   |
    | 5 |
    |   |
    \---/

  Note that there's a space between two adjacent letters.索引

注意兩個相鄰小寫字母間有一個空格。
CN

 

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.

對於每一個測試用例,第一行輸出到達成功位置的最小步驟數N。若5步內沒法到達則輸出-1。
隨後N行輸出每一個具體步驟。每一個步驟包含兩個整數,第一個表示面索引,第二個表示方向。1表示順時針,且-1表示逆時針。
若是給定配置則爲成功位置,輸出0。若存多解,擇一便可。
CN

 

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

 

題解

  IDA*,聽說暴力也是能夠的。

  水平太渣沒想到什麼高明的代價估計方法,取每面不符合的顏色種類數爲旋轉代價,上限爲3。

 

代碼 C++

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #define MX 54
 5 int maxDeep, n, mp[300], data[MX], opt[5][2],
 6 chgs[6][9] = {
 7     9, 10, 11, 23, 35, 34, 33, 21, 22,
 8     12, 13, 14, 26, 38, 37, 36, 24, 25,
 9     15, 16, 17, 29, 41, 40, 39, 27, 28,
10     18, 19, 20, 32, 44, 43, 42, 30, 31,
11     0, 1, 2, 5, 8, 7, 6, 3, 4,
12     45, 46, 47, 50, 53, 52, 51, 48, 49
13 }, chge[6][12] = {
14     44, 32, 20, 0, 3, 6, 12, 24, 36, 45, 48, 51,
15     35, 23, 11, 6, 7, 8, 15, 27, 39, 47, 46, 45,
16     38, 26, 14, 8, 5, 2, 18, 30, 42, 53, 50, 47,
17     41, 29, 17, 2, 1, 0, 9, 21, 33, 51, 52, 53,
18     11, 10, 9, 20, 19, 18, 17, 16, 15, 14, 13, 12,
19     33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44
20 };
21 int vle() {
22     int rtn = 0, i, j, tmp[6], siz;
23     for (i = 0; i < 6; ++i) {
24         memset(tmp, 0, sizeof tmp); siz = -1;
25         for (j = 0; j < 9; ++j) ++tmp[data[chgs[i][j]]];
26         for (j = 0; j < 6; ++j) if (tmp[j]) ++siz;
27         rtn = std::max(rtn, siz>3 ? 3 : siz);
28     }
29     return rtn;
30 }
31 void chg(int n, int drc) {
32     int i, tmpe[15], tmps[15];
33     if (~drc) {
34         memcpy(tmpe + 3, chge[n], sizeof chge[n]); memcpy(tmps + 2, chgs[n], sizeof chgs[n]);
35         memcpy(tmpe, tmpe + 12, sizeof(int)* 3); memcpy(tmps, tmps + 8, sizeof(int)* 2);
36     }
37     else {
38         memcpy(tmpe, &chge[n][3], sizeof(int)* 9); memcpy(tmps, &chgs[n][2], sizeof(int)* 6);
39         memcpy(tmpe + 9, chge[n], sizeof(int)* 3); memcpy(tmps + 6, chgs[n], sizeof(int)* 2);
40     }
41     for (i = 0; i < 12; ++i) tmpe[i] = data[tmpe[i]];
42     for (i = 0; i < 12; ++i) data[chge[n][i]] = tmpe[i];
43     for (i = 0; i < 8; ++i) tmps[i] = data[tmps[i]];
44     for (i = 0; i < 8; ++i) data[chgs[n][i]] = tmps[i];
45 }
46 
47 bool DFS(int deep) {
48     int i = vle();
49     if (i + deep>maxDeep) return 0;
50     if (!i) return 1;
51     for (i = 0; i < 6; ++i) {
52         chg(opt[deep][0] = i, opt[deep][1] = 1);
53         if (DFS(deep + 1)) return 1;
54         chg(i, -1);
55         chg(opt[deep][0] = i, opt[deep][1] = -1);
56         if (DFS(deep + 1)) return 1;
57         chg(i, 1);
58     }
59     return 0;
60 }
61 
62 int main() {
63     mp['w'] = 0; mp['r'] = 1; mp['g'] = 2; mp['b'] = 3; mp['o'] = 4; mp['y'] = 5;
64     int t, i;
65     char c;
66     scanf("%d", &t);
67     while (t--) {
68         for (i = 0; i < MX; ++i) {
69             scanf(" %c", &c); data[i] = mp[c];
70         }
71         for (maxDeep = vle(); maxDeep < 6 && !DFS(0); ++maxDeep);
72         if (maxDeep < 6) {
73             printf("%d\n", maxDeep);
74             for (i = 0; i < maxDeep; ++i) printf("%d %d\n", opt[i][0], opt[i][1]);
75         }
76         else puts("-1");
77     }
78     return 0;
79 }
相關文章
相關標籤/搜索