8 digital problems, that is, in a 3 × 3 matrix, there are 8 numbers (1 to 8) and a space, from one state to another, each time, you can only move a number adjacent to a space.
AOJ-417-8 digital
Http://icpc.ahu.edu.cn/OJ/Problem.aspx? Id = 417
This is the minimum number of steps for conversion, which can be solved by BFS. There are 9 in total! = In 362880 cases, the key is how to mark the accessed status to ensure that the status obtained by each search is the minimum number of steps. Here, the string can be converted to the corresponding integer for processing, use Kanto to expand to save storage space
Conto expand: X = an * (n-1 )! + An-1 * (n-2 )! +... + Ai * (I-1 )! +... + A2 * 1! + A1 * 0!
Ai is the number (0 <= ai <I) in the number that does not appear currently)
For example, expand 3 5 7 4 1 2 9 6 8
X = 2*8! + 3*7! + 4*6! + 2*5! + 0*4! + 0*3! + 2*2! + 0*1! + 0*0! = 98884
# Include <stdio. h> # include <string. h> # include <stdlib. h> char a [363000] [9]; // a total of 9! = In 362880 cases, char goal [9]; char visit [363000]; int dis [363000]; int dir [4] [2] = {-}, {0,-1}; int c [9] =, 24,120,720,504,}; int find (char str [9]) // converts a string into an integer {int I, j, k; int f [10]; int sum = 0; memset (f, 0, sizeof (f); for (I = 0; I <9; I ++) {k = 0; for (j = 0; j <8; j ++) if (j <str [I] &! F [j]) k ++; f [str [I] = 1; sum + = k * c [8-i];} return sum;} int bfs () {int I, j, t, flag; int head, tail; int x, y, z; int nx, ny, nz; memset (dis, 0, sizeof (dis); // execute a memset (visit, 0, sizeof (visit) in each State )); // The marked points cannot be repeated t = find (a [0]); visit [t] = 1; head = 0; tail = 1; while (head <tail) {flag = 1; for (I = 0; I <9; I ++) if (a [head] [I]! = Goal [I]) // if the target status is the same, stop searching {flag = 0; break;} if (flag) return dis [head]; for (I = 0; I <9; I ++) // locate 0. if (a [head] [I] = 0) {x = I/3; y = I % 3; z = I; break;} for (I = 0; I <4; I ++) {nx = x + dir [I] [0]; ny = y + dir [I] [1]; nz = nx * 3 + ny; if (0 <= nx & nx <3 & 0 <= ny & ny <3) {for (j = 0; j <9; j ++) a [tail] [j] = a [head] [j]; a [tail] [z] = a [head] [nz]; // perform a move, that is, non-0 elements and 0 exchanges a [tail] [nz] = 0; t = find (a [tail]); if (! Visit [t]) {visit [t] = 1; dis [tail] = dis [head] + 1; tail ++ ;}} head ++ ;} return-1 ;}int main () {int I, ans; for (I = 0; I <9; I ++) scanf ("% d ", & a [0] [I]); for (I = 0; I <9; I ++) scanf ("% d", & goal [I]); ans = bfs (); if (ans =-1) printf ("Impossible \ n"); else printf ("% d \ n", ans); return 0 ;}
POJ-1077-Eight
Http://poj.org/problem? Id = 1077
This question does not require a minimum number of steps, and requires the path strength to move. It is similar to the previous question. Use BFS, record the path strength, and finally output the result in reverse order.
# Include <stdio. h> # include <string. h> # include <stdlib. h> char a [363000] [9]; // a total of 9! = In 362880 cases, char goal [9]; char visit [363000]; int dis [363000]; int step [363000]; // int pre [363000] from the previous step; // int dir [4] [2] = }, {0, 1}, {0,-1 }}; char name [4] = {'D', 'U', 'R', 'L '}; int c [9] = {24,120,720,504,}; void init () {int I; for (I = 0; I <8; I ++) goal [I] = I + 1; goal [8] = 0;} int find (char str [9]) // converts a string into an integer {int I, j, k; int f [10]; int sum = 0; memset (f, 0, sizeof (f); for (I = 0; I <9; I ++) {k = 0; for (j = 0; j <8; j ++) if (j <str [I] &! F [j]) k ++; f [str [I] = 1; sum + = k * c [8-i];} return sum;} int bfs () {int I, j, t, flag; int head, tail; int p, q, temp; int x, y, z; int nx, ny, nz; char sol [5000]; memset (dis, 0, sizeof (dis); // perform a few steps for memset (visit, 0, sizeof (visit) in each State )); // The marked points cannot be repeated by memset (step, 0, sizeof (step); t = find (a [0]); visit [t] = 1; step [0] = pre [0] =-1; head = 0; tail = 1; while (head <tail) {flag = 1; for (I = 0; I <9; I ++) if (a [head] [I]! = Goal [I]) // if the target status is the same, stop searching {flag = 0; break;} if (flag) // print path strength {temp = 0; while (head) {p = pre [head]; // The status of the previous step q = step [head]; // from the previous step to sol [temp ++] = name [q]; head = p;} for (I = temp-1; I> = 0; I --) printf ("% c", sol [I]); printf ("\ n "); return 1 ;}for (I = 0; I <9; I ++) // locate 0 if (a [head] [I] = 0) {x = I/3; y = I % 3; z = I; break;} for (I = 0; I <4; I ++) {nx = x + dir [I] [0]; // move the 0 element ny = y + dir [I] [1]; nz = nx * 3 + ny; if (0 <= nx & nx <3 & 0 <= ny & ny <3) {for (j = 0; j <9; j ++) a [tail] [J] = a [head] [j]; a [tail] [z] = a [head] [nz]; // perform a move, that is, non-0 elements and 0 exchanges a [tail] [nz] = 0; t = find (a [tail]); if (! Visit [t]) {visit [t] = 1; dis [tail] = dis [head] + 1; pre [tail] = head; // step [tail] = I from the previous step; // from the direction of tail ++;} head ++;} return-1 ;} int main () {int I, k, ans; char ss [50]; k = 0; gets (ss); for (I = 0; I <strlen (ss ); I ++) {if ('0' <= ss [I] & ss [I] <= '9 ') a [0] [k ++] = (ss [I]-'0'); else if (ss [I] = 'X ') a [0] [k ++] = 0;} init (); ans = bfs (); if (ans =-1) printf ("unsolvable \ n "); return 0 ;}