Poj3366cubic eight-puzzle (Stereo 8 digital, bidirectional BFS + 6 hexadecimal compression)

Source: Internet
Author: User
Cubic eight-puzzle
Time limit:5000 Ms   Memory limit:65536 K
Total submissions:1301   Accepted:434

Description

Let's play a puzzle using eight cubes placed on a 3 × 3 board leaving one empty square.

Faces of cubes are painted with three colors. as a puzzle step, you can roll one of the cubes to a adjacent empty square. your goal is to make the specified color pattern visible from above by a number of such steps.

The rules of this puzzle are as follows.

  1. Coloring of cubes:All the cubes area colored in the same way as shown in Figure 1. The opposite faces have the same color.

    Figure 1: coloring of a cube

  2. Initial board state:Eight cubes are placed on the 3 × 3 board leaving one empty square. All the cubes have the same orientation as shown in Figure 2. As shown in the figure, squares on the board are givenXAndYCoordinates,
    (1, 1), (1, 2 ),..., And (3, 3). The position of the initially empty square may vary.

    Figure 2: initial board State

  3. Rolling cubes:At each step, we can choose one of the cubes adjacent to the empty square and roll it into the empty square, leaving the original position empty. Figure 3 shows an example.

    Figure 3: rolling a cube

  4. Goal:The goal of this puzzle is to arrange the cubes so that their top faces form the specified color pattern by a number of cube rolling steps described above.

Your task is to write a program that finds the minimum number of steps required to make the specified color pattern from the given initial state.

Input

The input is a sequence of datasets. the end of the input is indicated by a line containing two zeros separated by a space. the number of datasets is less than 16. each dataset is formatted as follows.

X Y  
F11 F21 F31
F12 F22 F32
F13 F23 F33

The first line contains two integersXAndYSeparated by a space, indicating the position (X,Y) Of the initially empty square. The valuesXAndYAre 1, 2, or 3.

The following three lines specify the color pattern to make. Each line contains three charactersF1J,F2J, AndF3J, Separated by a space. CharacterFijIndicates
The top color of the cube, if any, at the position (I,J) As follows:

B:Blue,

W:White,

R:Red,

E:The square is empty.

There is exactly one'E'Character in each dataset.

Output

For each dataset, output the minimum number of steps to achieve the goal, when the goal can be reached within 30 steps. Otherwise, output"-1"For the dataset.

Sample Input

1 2 W W W E W W W W W 2 1 R B W R W W E W W 3 3 W B W B R E R B R 3 3 B W R B W R B E R 2 1 B B B B R B B R E 1 1 R R R W W W R R E 2 1 R R R B W B R R E 3 2 R R R W E W R R R0 0

Sample output

0 3 13 23 29 30 -1 -1

Source

It took another day to solve this problem in Japan 2006... Orz male... This is an example of the 8 digital problem, but it is a little different. There are 8 three-dimensional cubes in the 3*3 area, leaving a space for easy movement. The moving rule is: the cube next to a space can scroll to the space position, and the original position of the cube becomes a space. The six sides of each cube have three colors, and the opposite side have the same color, namely, white, blue, and red. In the initial state, each cube is placed in the same way. The front is white, the front is red, the right is blue, and the space position is given. Given an initial space position and the color distribution of the above table in the final state, determine whether the minimum number of steps can be output from the initial state to the final state within 30 steps. No, output-1. Note that the given final state is only the color distribution on the above table, and the colors on other faces are not required. Question Analysis: BFs. This question has a large number of States. If one-way BFS is used, the time-space complexity is too high. Therefore, two-way BFS is used. The first thing to solve is the issue of determining the weight. Unlike the two-dimensional eight-digit digital, each location has only one status. Therefore, you can use Kanto to determine the weight, the small square in each position has 6 States, plus spaces, and each position has 7 states. The total number of States is 7 ^ 9, which is obviously too large. Considering that only one of the nine positions can be a space, you can separate the space to determine the weight, so that the space complexity is reduced to 6 ^ 8*9, barely acceptable. If the queue is manually written with two cyclic queues, it will save a lot of memory (it is enough to open the space of the cyclic queue by 100005 after testing ). Next, consider the State representation. Each cube has six States (think about why). How do we express these six states. The space for this question is only kb, and nearly half of the reusable array is required, and the overhead of two queues is required. Therefore, the space of each search node must be saved. If an array is used to store each State, the memory is obviously insufficient and the judgment will be slow. After further analysis, we can find that the status of each position in the remaining 8 locations is 0-5 except for one space. That is to say, the total status is 6 ^ 8 from 00000000-55555555, we can compress the status of these eight locations into a 6-digit integer, which makes it easy to determine the number of duplicates. Each move changes the number of at most three positions, the specific process is still well aligned on the draft paper. Do not make any mistakes and it is not easy to debug. Note that there is only one initial state of this question, that is, all the small squares are placed in the same red and right blue before the white, the final state only considers the upper surface, so the final state is not unique, there are 2 ^ 8 = 256 final states. After writing the script, I used g ++ to submit the script. I used C ++ to submit the script. It was later found that the problem was caused by the number of two-way searches. We usually search both positive and negative, but this question is different. There is only one status at the beginning of the forward, and there are 256 statuses at the beginning of the reverse direction. In this case, the positive and reverse directions will not be averaged during expansion, if both positive and negative search results are half done, the efficiency will decrease. Therefore, we consider moving forward searches several more steps to reduce the burden on reverse searches. After more than a dozen times of submission, we found that the time-space efficiency was the highest when we searched for 21 steps forward and 9 steps backward. For details, see the code:
# Include <iostream> # include <cstdio> # include <cstring> # include <cctype> using namespace STD; const int d1 = 21; const int D2 = 9; const int M = 100005; const int n = 1679616; // 6 ^ 8 bool flag [2] [N] [9]; // 3690 kbint FAC [] =, 36,216,129,}; // six statuses: // top right of the status code // 0 w r B // 1 w B r // 2 r w B // 3 r B w // 4 B W R // 5 B R Wint roll [6] [2] = {2, 5 }, {}, {}, {5, 1}, {1, 2}, {3, 0}; // each of the six statuses changes to the new status ST in the left and right directions. Ruct node {int state; short int POs, step;} SS, now; struct que {struct node T [m]; int head, tail; void Init () {head = tail;} bool empty () {return head = tail;} struct node top () {return T [head];} void POP () {head ++; if (Head = m) Head = 0;} void push (struct node A) {T [tail] = A; tail ++; If (tail = m) tail = 0; If (tail + 1 = head) printf ("queue full \ n") ;}} Q [2]; int X, Y; int endstate [10]; int Endpos; void DFS (INT cur, int sum, int DP) {If (cur =-1) {ss. state = sum; SS. pos = endpos; SS. step = 0; Q [1]. push (SS); flag [1] [ss. state] [ss. pos] = 1; return;} If (endstate [cur] =-1) DFS (cur-1, sum, DP); else {int I; for (I = endstate [cur]; I <= endstate [cur] + 1; I ++) DFS (cur-1, sum + I * FAC [DP], DP + 1) ;}} int getdigit (int A, int B) // obtain the BTH + 1 position {int ret of the low position in hexadecimal number; a/= FAC [B]; ret = A % 6; return re T;} int main () {int I, j, k; char s [3]; while (scanf ("% d", & Y, & X ), (x + y) {for (I = 0; I <3; I ++) {for (j = 0; j <3; j ++) {scanf ("% s", S); Switch (* s) {Case 'W': endstate [I * 3 + J] = 0; break; Case 'r ': endstate [I * 3 + J] = 2; break; Case 'B': endstate [I * 3 + J] = 4; break; Case 'E ': endstate [I * 3 + J] =-1; endpos = I * 3 + J; break ;}} X --; y --; Q [0]. init (); Q [1]. init (); memset (flag, 0, sizeof (flag ); SS. pos = x * 3 + Y; SS. state = ss. step = 0; Q [0]. push (SS); flag [0] [0] [ss. pos] = 1; DFS (8, 0); // If (flag [1] [Q [0]. top (). state] [Q [0]. top (). pos]) {printf ("0 \ n"); continue;} int ans =-1; int T1, T2; k = 0; For (j = 0; j <d1 & Ans <0; j ++) {for (I = 0; I <= 1; I ++) // two queues 0 forward search 1 reverse search {While (! Q [I]. Empty () // & Q [I]. Top (). Step = J) {if (I) // reverse {If (! (Q [I]. Top (). Step = K & K <D2) break;} else {If (! (Q [I]. top (). step = J) break;} Now = Q [I]. top (); Q [I]. pop (); If (now. pos> = 3) // empty up {Ss = now; SS. step ++; T1 = getdigit (now. state, 10-now. pos); t2 = roll [T1] [0]; SS. pos-= 3; SS. state-= (T1 * FAC [10-now. pos]); // T1 = getdigit (now. state, 9-now. pos); SS. state-= (T1 * FAC [9-now. pos]); SS. state + = (T1 * FAC [10-now. pos]); T1 = getdigit (now. state, 8-now. pos); SS. state-= (T1 * FAC [8- Now. pos]); SS. state + = (T1 * FAC [9-now. pos]); SS. state + = (T2 * FAC [8-now. pos]); // If (! Flag [I] [ss. state] [ss. pos]) {flag [I] [ss. state] [ss. pos] = 1; if (flag [1-I] [ss. state] [ss. pos]) {ans = I? J + K + 2: J + k + 1; break;} Q [I]. push (SS) ;}} if (now. pos <= 5) // empty down {Ss = now; SS. step ++; SS. pos + = 3; T1 = getdigit (now. state, 5-now. pos); t2 = roll [T1] [0]; SS. state-= (T1 * FAC [5-now. pos]); T1 = getdigit (now. state, 6-now. pos); SS. state + = (T1 * FAC [5-now. pos]); SS. state-= (T1 * FAC [6-now. pos]); T1 = getdigit (now. state, 7-now. pos); SS. state + = (T1 * FAC [6-now. pos]); SS. sta Te-= (T1 * FAC [7-Now. Pos]); SS. State + = (T2 * FAC [7-Now. Pos]); If (! Flag [I] [ss. state] [ss. pos]) {flag [I] [ss. state] [ss. pos] = 1; if (flag [1-I] [ss. state] [ss. pos]) {ans = I? J + K + 2: J + k + 1; break;} Q [I]. push (SS) ;}} if (now. pos % 3) // Empty left {Ss = now; SS. step ++; SS. pos --; T1 = getdigit (now. state, 8-now. pos); t2 = roll [T1] [1]; SS. state-= (T1 * FAC [8-now. pos]); SS. state + = (T2 * FAC [8-now. pos]); If (! Flag [I] [ss. state] [ss. pos]) {flag [I] [ss. state] [ss. pos] = 1; if (flag [1-I] [ss. state] [ss. pos]) {ans = I? J + K + 2: J + k + 1; break;} Q [I]. push (SS) ;}} if (now. pos + 1) % 3) // empty right {Ss = now; SS. step ++; SS. pos ++; T1 = getdigit (now. state, 7-now. pos); t2 = roll [T1] [1]; SS. state-= (T1 * FAC [7-now. pos]); SS. state + = (T2 * FAC [7-now. pos]); If (! Flag [I] [ss. state] [ss. pos]) {flag [I] [ss. state] [ss. pos] = 1; if (flag [1-I] [ss. state] [ss. pos]) {ans = I? J + K + 2: J + k + 1; break;} Q [I]. push (SS) ;}}if (ANS> 0) break;} If (k <D2) K ++;} printf ("% d \ n ", ans);} return 0;} // forward 12 steps backward 18 steps :..... // forward 13 steps back 17 steps: Wrong answer // forward 14 steps back 16 steps: Wrong answer // forward 15 steps back 15 steps: 56664k4813ms // forward 16 steps backward 14 steps: 56892k4000ms // forward 17 steps backward 13 steps: 57347k2782ms // forward 18 steps backward 12 steps: 58192k2016ms // Forward 19 steps backward 11 steps: 51712k1547ms // forward to 20 steps back 10 steps: 47212k1282ms // forward to 21 steps back 9 steps: 45848k1204ms 31340k1204ms (cyclic queue to 100005) // forward to 22 steps back 8 steps: 47728k1391ms // forward 23 steps back 7 steps: 51968k1704ms // forward 24 steps back 6 steps :... // forward step 25 to Step 5 :... /* 2 1R B wr w We w W3 3 w B wb r er B R3 3B w rb e R2 1B B BB R E1 1R R RW W WR R E2 1R r rb w br r E3 2R r rw e wr R R1 2 w we w ww w W0 0 */

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.