杭电 p1043 acm eight 八数码

Eight

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1852    Accepted Submission(s): 532
Special Judge

Problem Description
The15-puzzle has been around for over 100 years; even if you don't know itby that name, you've seen it. It is constructed with 15 sliding tiles,each with a number from 1 to 15 on it, and all packed into a 4 by 4frame with one tile missing. Let's call the missing tile 'x'; theobject of the puzzle is to arrange the tiles so that they are orderedas:
 1  2  3  4

 5  6  7  8

 9 10 11 12

13 14 15  x


wherethe only legal operation is to exchange 'x' with one of the tiles withwhich it shares an edge. As an example, the following sequence of movessolves a slightly scrambled puzzle:
 1  2  3  4     1  2  3  4     1  2  3  4     1  2  3  4

 5  6  7  8     5  6  7  8     5  6  7  8     5  6  7  8

 9  x 10 12     9 10  x 12     9 10 11 12     9 10 11 12

13 14 11 15    13 14 11 15    13 14  x 15    13 14 15  x

            r->            d->            r->


Theletters in the previous row indicate which neighbor of the 'x' tile isswapped with the 'x' tile at each step; legal values are 'r','l','u'and 'd', for right, left, up, and down, respectively.

Not allpuzzles can be solved; in 1870, a man named Sam Loyd was famous fordistributing an unsolvable version of the puzzle, and
frustratingmany people. In fact, all you have to do to make a regular puzzle intoan unsolvable one is to swap two tiles (not counting the missing 'x'tile, of course).

In this problem, you will write a program for solving the less well-known 8-puzzle, composed of tiles on a three by three
arrangement.
 

 

Input
Youwill receive, several descriptions of configuration of the 8 puzzle.One description is just a list of the tiles in their initial positions,with the rows listed from top to bottom, and the tiles listed from leftto right within a row, where the tiles are represented by numbers 1 to8, plus 'x'. For example, this puzzle

1 2 3
x 4 6
7 5 8

is described by this list:

1 2 3 x 4 6 7 5 8
 

 

Output
Youwill print to standard output either the word ``unsolvable'', if thepuzzle has no solution, or a string consisting entirely of the letters'r', 'l', 'u' and 'd' that describes a series of moves that produce asolution. The string should include no spaces and start at thebeginning of the line. Do not print a blank line between cases.
 

 

Sample Input
2  3  4  1  5  x  7  6  8
 

 

Sample Output
ullddrurdllurdruldr
 

 

Source
South Central USA 1998 (Sepcial Judge Module By JGShining)
 

 

Recommend
JGShining
 

用一个图表示,每个结点代表一个格局,结点编号与{0, 1, 2, 3, 4, 5, 6, 7, 8}排序的编号一一对应,0表示的是'x',用bfs搜索从{1, 2, 3, 4, 5, 6, 7, 8, 0}(编号为46233)到各个输入所应的结点的路径。

#include #include #include #include using namespace std; #define MAX 362880 #define BUF 100000 #define WHITE 0 #define GRAY 1 #define BLACK 2 #define UP 0 #define RIGHT 1 #define DOWN 2 #define LEFT 3 #define NIL -1 #define TARGET 46233 int graph[MAX][4]; int color[MAX]; int enter[MAX]; int pre[MAX]; int mat[10] = {1, 2, 3, 4, 5, 6, 7, 8, 0, NIL}; int fac[9] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320}; char path[4] = {'d', 'l', 'u', 'r'}; int dest; struct queue { queue() { head = tail = 0; } bool empty() { return head == tail; } void push(int v) { buf[tail] = v; tail =(tail + 1) % BUF; } void pop() { head =(head + 1) % BUF; } int front() { return buf[head]; } int buf[BUF]; int head; int tail; }vqueue; void bfs() { while(!vqueue.empty() && color[dest] == WHITE) { int v = vqueue.front(); vqueue.pop(); color[v] = BLACK; for(int i=0; i<4; ++i) { int neighbor = graph[v][i]; if(neighbor != NIL && color[neighbor] == WHITE) { vqueue.push(neighbor); color[neighbor] = GRAY; enter[neighbor] = i; pre[neighbor] = v; } } } } void print_path(int v) { if(pre[v] == NIL) { printf("/n"); return; } printf("%c", path[enter[v]]); print_path(pre[v]); } int order(int idx) { int ret = 0; int num = mat[idx]; while(mat[idx] != NIL) { if(mat[idx] < num) ++ret; ++idx; } return ret; } int hash() { int ret = 0; for(int i=0; i<9; ++i) ret += order(i) * fac[8 - i]; return ret; } void make_graph() { int v = hash(); int idx_x = find(mat, mat + 9, 0) - mat; if(idx_x - 3 >= 0) { swap(mat[idx_x], mat[idx_x - 3]); graph[v][UP] = hash(); swap(mat[idx_x], mat[idx_x - 3]); } if((idx_x + 1)/ 3 == idx_x / 3) { swap(mat[idx_x], mat[idx_x + 1]); graph[v][RIGHT] = hash(); swap(mat[idx_x], mat[idx_x + 1]); } if(idx_x + 3 < 9) { swap(mat[idx_x], mat[idx_x + 3]); graph[v][DOWN] = hash(); swap(mat[idx_x], mat[idx_x + 3]); } if(idx_x >= 1 && (idx_x - 1)/ 3 == idx_x / 3) { swap(mat[idx_x], mat[idx_x - 1]); graph[v][LEFT] = hash(); swap(mat[idx_x], mat[idx_x - 1]); } } void perm(int idx) { if(mat[idx] == NIL) { make_graph(); return; } for(int i=idx; i<9; ++i) { swap(mat[idx], mat[i]); perm(idx + 1); swap(mat[idx], mat[i]); } } void get_mat() { int i = 0; int cnt = 0; char str[100]; if(!(cin.getline(str, sizeof(str)))) exit(0); while(cnt < 9) { if(str[i] == 'x') { mat[cnt] = 0; ++cnt; } else if(str[i] <= '8' && str[i] >= '1') { mat[cnt] = str[i] - '0'; ++cnt; } ++i; } dest = hash(); } void init() { fill(graph[0], graph[0] + MAX * 4, NIL); perm(0); fill(color, color + MAX, WHITE); fill(enter, enter + MAX, NIL); fill(pre, pre + MAX, NIL); vqueue.push(TARGET); color[TARGET] = GRAY; } int main() { init(); while(true) { get_mat(); bfs(); if(color[dest] == WHITE) printf("unsolvable/n"); else print_path(dest); } return 0; }

你可能感兴趣的:(ACM)