Poj 3131 cubic eight-puzzle (bidirectional BFS + deeply controlled octal digital)

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

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
 
Question: This is a three-dimensional 8 digital problem, but it is a little different. There are eight 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.
 
Idea: BFs. This question has a large number of States and requires a high level of time space. If one-way BFS is used, the time and 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.
In this case, we need to use the hexadecimal number to indicate the status, and then determine the weight. The final problem is to simulate the rolling of the square and scroll in four directions, make it clear on the draft.
PS: this topic also indicates that, because there is only one final status but two ^ 8 statuses at the beginning, the depth of searching from the front and back is not the same as that of searching from the back and forth, so that more searching points can be ensured in the front and back. in this way, the double search is expanded along the prism. Previously and backward: layer 21 goes forward from the back to the back: Layer 9.
 
Feeling: the program code for this question is still quite long, so you have to think clearly and think about it before you start it. Otherwise, debugging will be difficult to do.
 
Code: (the STL used by my program can also be changed to its own queue. It will be a little faster and easier to see. I will only paste STL code)
// Memory 31352 kb time 2250 MS
# Include <iostream> # include <cstdio> # include <cstring> # include <queue> # define maxn 1679616 // 6 ^ 8 using namespace STD; int n, m, X, y, ANS, dfspos; int six [] = {36,216,129,}; int State [3] [3]; // int roll [6] [4] = // status after rolling {, 5, ,}; bool vis1 [9] [maxn]; bool vis2 [9] [maxn]; int MP [9]; int DX [] = {-,}; int dy [] = {,-}; int undir [] = {1, 0, 3, 2}; int dight [8]; struct node {int Pos; int sta; int step;} cur, now; queue <node> q1, Q2; int getdight (int xx, int K) // It is extracted in decimal format. If (k = 0) T = XX % 6; else {T = 1; for (I = 1; I <= K; I ++) T * = 6; t = (XX/T) % 6;} return t;} bool BFS (int K) {int I, j, mi, cnt1, cnt2, NPOs, nsta, NX, NY, temp, nstep, flag; int Tx, Ty, TPOs, tsta, tstadt; memset (vis1, 0, sizeof (vis1); While (! Q1.empty () q1.pop (); cur. pos = K; cur. sta = 0; vis1 [k] [0] = 1; cur. step = 0; q1.push (cur); cnt1 = 0; cnt2 = 0; while (1) {flag = 0; while (q1.front (). step <= cnt1 &&! Q1.empty () {flag = 1; now = q1.front (); q1.pop (); NPOs = now. pos; nsta = now. sta; nstep = now. step; Nx = NPOs/3; ny = NPOs % 3; if (vis2 [NPOs] [nsta]) {ans = nstep + cnt2; return true ;} // printf ("POS: % d step: % d sta: % d NX: % d NY: % d \ n", NPOs, nstep, nsta, NX, NY ); for (I = 0; I <8; I ++) {dight [I] = getdight (nsta, I) ;}for (I = 0; I <4; I ++) {Tx = NX + dx [I]; ty = ny + dy [I]; if (TX> = 0 & TX <3 & ty> = 0 & ty <3 & nstep <21) {// printf ("TX: % d TY: % d \ n ", TX, Ty); TPOs = TX * 3 + ty; if (I = 2 | I = 3) // you can directly process {mi = NPOs> TPOs? TPOs: NPOs; tstadt = roll [dight [MI] [undir [I]; tsta = nsta-six [MI] * dight [MI] + six [MI] * tstadt; If (! Vis1 [TPOs] [tsta]) {vis1 [TPOs] [tsta] = 1; cur. step = nstep + 1; cur. pos = TPOs; cur. sta = tsta; q1.push (cur) ;}} else if (I = 0) // scroll down to the value that affects the number of three {tstadt = roll [dight [TPOs] [undir [I]; tsta = nsta; For (j = TPOs; j <NPOs; j ++) {tsta-= six [J] * dight [J];} tsta + = tstadt * Six [npos-1]; for (j = TPOs + 1; j <NPOs; j ++) {tsta + = six [J-1] * dight [J];} If (! Vis1 [TPOs] [tsta]) {vis1 [TPOs] [tsta] = 1; cur. step = nstep + 1; cur. pos = TPOs; cur. sta = tsta; q1.push (cur) ;}} else if (I = 1) // The value of the three numbers should also be affected to scroll up {tstadt = roll [dight [tpos-1] [undir [I]; tsta = nsta; For (j = NPOs; j <TPOs; j ++) {tsta-= six [J] * dight [J];} tsta + = tstadt * Six [NPOs]; for (j = NPOs; j <tpos-1; j ++) {tsta + = six [J + 1] * dight [J]; // error at the beginning. j forgot + 1} If (! Vis1 [TPOs] [tsta]) {vis1 [TPOs] [tsta] = 1; cur. step = nstep + 1; cur. pos = TPOs; cur. sta = tsta; q1.push (cur) ;}}}}if (cnt1 <21) cnt1 ++; // you can specify the depth of layer-21 While (q2.front (). step <= cnt2 &&! Q2.empty () {flag = 1; now = q2.front (); q2.pop (); NPOs = now. pos; nsta = now. sta; nstep = now. step; Nx = NPOs/3; ny = NPOs % 3; if (vis1 [NPOs] [nsta]) {ans = cnt1 + nstep; return true ;} // printf ("POS: % d step: % d sta: % d NX: % d NY: % d \ n", NPOs, nstep, nsta, NX, NY ); for (I = 0; I <8; I ++) {dight [I] = getdight (nsta, I) ;}for (I = 0; I <4; I ++) {Tx = NX + dx [I]; ty = ny + dy [I]; if (TX> = 0 & TX <3 & ty> = 0 & ty <3 & nstep <9) {// printf ("TX: % d TY: % d \ n", TX, Ty); TPOs = TX * 3 + ty; if (I = 2 | I = 3) // you can directly process {mi = NPOs> TPOs? TPOs: NPOs; tstadt = roll [dight [MI] [undir [I]; tsta = nsta-six [MI] * dight [MI] + six [MI] * tstadt; If (! Vis2 [TPOs] [tsta]) {vis2 [TPOs] [tsta] = 1; cur. step = nstep + 1; cur. pos = TPOs; cur. sta = tsta; q2.push (cur) ;}} else if (I = 0) // scroll down to the value that affects the number of three {tstadt = roll [dight [TPOs] [undir [I]; tsta = nsta; For (j = TPOs; j <NPOs; j ++) {tsta-= six [J] * dight [J];} tsta + = tstadt * Six [npos-1]; for (j = TPOs + 1; j <NPOs; j ++) {tsta + = six [J-1] * dight [J];} If (! Vis2 [TPOs] [tsta]) {vis2 [TPOs] [tsta] = 1; cur. step = nstep + 1; cur. pos = TPOs; cur. sta = tsta; q2.push (cur) ;}} else if (I = 1) // The value of the three numbers should also be affected to scroll up {tstadt = roll [dight [tpos-1] [undir [I]; tsta = nsta; For (j = NPOs; j <TPOs; j ++) {tsta-= six [J] * dight [J];} tsta + = tstadt * Six [NPOs]; for (j = NPOs; j <tpos-1; j ++) {tsta + = six [J + 1] * dight [J];} If (! Vis2 [TPOs] [tsta]) {vis2 [TPOs] [tsta] = 1; cur. step = nstep + 1; cur. pos = TPOs; cur. sta = tsta; q2.push (cur) ;}}} if (cnt2 <9) cnt2 ++; // no more than 9 steps forward from the back if (! Flag) return false;} void DFS (int kk, int SSTA, int TT) // Several numbers have been added to the access status {int I, j, temp; if (KK> 8) {If (! Vis2 [dfspos] [SSTA]) // The dfspos must use the global variable {vis2 [dfspos] [SSTA] = 1; cur. step = 0; cur. sta = SSTA; // printf ("POS: % d SSTA: % d \ n", dfspos, SSTA); q2.push (cur);} return ;} if (MP [Kk] =-1) {dfspos = KK; DFS (KK + 1, SSTA, TT );} else {temp = MP [Kk] * Six [TT]; DFS (KK + 1, SSTA + temp, tt + 1); temp = (MP [Kk] + 1) * Six [TT]; DFS (KK + 1, SSTA + temp, tt + 1);} int main () {int I, j, T, TST, TPOs, temp; char s [3]; State [0] [1] = 0; State [0] [2] = 1; State [1] [0] = 2; State [1] [2] = 3; State [2] [0] = 4; State [2] [1] = 5; while (scanf ("% d", & X, & Y), X | Y) {X --; y --; t = y * 3 + X; for (I = 0; I <3; I ++) {for (j = 0; j <3; j ++) {scanf ("% s", S ); temp = I * 3 + J; If (s [0] = 'W') MP [temp] = 0; else if (s [0] = 'R ') MP [temp] = 2; else if (s [0] = 'B') MP [temp] = 4; else {MP [temp] =-1; TPOs = I * 3 + J ;}} cur. pos = TPOs; memset (vis2, 0, sizeof (vis2); While (! Q2.empty () q2.pop (); DFS (, 0); // Add the final state to the queue if (BFS (t) printf ("% d \ n ", ans); else printf ("-1 \ n");} return 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.