20091006
A classic question. The following is the original question and my code.
1077 eight
Time limit:1000 ms |
|
Memory limit:65536 K |
Total submissions:6197 |
|
Accepted:2670 |
|
Special Judge |
Description
The 15-puzzle has been around for over 100 years; even if you don't know it by that name, you 've got it. it is constructed with 15 sliding tiles, each with a number from 1 to 15 on it, and all packed into a 4
4 frame with one tile missing. Let's call the missing tile 'X'; the object of the puzzle is to arrange the tiles so that they are ordered:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 x
Where the only legal operation is to exchange 'X' with one of the tiles with which it shares an edge. As an example, the following sequence of moves solves 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->
The letters in the previous row indicate which neighbor of the 'X' tile is swapped with the 'X' tile at each step; legal values are 'R', 'l ', 'U' and 'D', for right, left, up, and down, respectively.
Not all puzzles can be solved; in 1870, a man named Sam Loyd was famous for distributing an unsolvable version of the puzzle, and
Frustrating extends people. In fact, all you have to do to make a regular puzzle into an 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
You will receive a description of a configuration of the 8 puzzle. the 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 left
To right within a row, where the tiles are represented by numbers 1 to 8, 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
You will print to standard output either the word ''unsolvable'', if the puzzle has no solution, or a string consisting entirely of the letters 'R', 'l ', 'U' and 'D' that describes a series of moves that produce
A solution. The string shocould include no spaces and start at the beginning of the line.
Sample Input
2 3 4 1 5 x 7 6 8
Sample output
ullddrurdllurdruldr
Source
South Central USA 1998
# Include <stdio. h>
# Include <stdlib. h>
# Include <math. h>
Typedef struct Node
{
Char sta [3] [3];
Char posr, POSC;
Char ope;
Int lev;
Int DIS;
Struct node * next;
} Node;
Int Hash (node * cur)
{
Static int I, j, sum, Pro, Rev;
Sum = 0;
For (PRO = I = 1; I <9; I ++)
{
Pro * = I;
For (REV = J = 0; j <I; j ++)
If (cur-> sta [0] [J]> cur-> sta [0] [I])
Rev ++;
Sum + = Pro * Rev;
}
Return sum;
}
Void change (node * cur, char OPE)
{
Char T;
T = cur-> sta [cur-> posr] [cur-> POSC];
Switch (OPE)
{
Case 'U ':
Cur-> sta [cur-> posr] [cur-> POSC] = cur-> sta [cur-> posr + 1] [cur-> POSC];
Cur-> posr ++;
Break;
Case 'D ':
Cur-> sta [cur-> posr] [cur-> POSC] = cur-> sta [cur-> posr-1] [cur-> POSC];
Cur-> posr --;
Break;
Case 'l ':
Cur-> sta [cur-> posr] [cur-> POSC] = cur-> sta [cur-> posr] [cur-> POSC + 1];
Cur-> POSC ++;
Break;
Case 'r ':
Cur-> sta [cur-> posr] [cur-> POSC] = cur-> sta [cur-> posr] [cur-> posc-1];
Cur-> POSC --;
Break;
}
Cur-> sta [cur-> posr] [cur-> POSC] = T;
}
Void printpre (node * cur, char table [])
{
Char T;
If (t = table [Hash (cur)])! = '\ B ')
{
Change (cur, t );
Printpre (cur, table );
Putchar (t );
}
}
Void end (node * cur, char table [])
{
Change (cur, cur-> OPE );
Printpre (cur, table );
Putchar (cur-> OPE );
}
Int getpar (node * cur)
{
Int I, j, sum = 0;
For (I = 1; I <9; I ++)
For (j = 0; j <I; j ++)
If (* cur-> Sta) [J]! = '9' & (* cur-> Sta) [J]> (* cur-> Sta) [I])
Sum ++;
Return sum % 2;
}
Void brushdis (node * cur)
{
Static int sum, I, j, T;
For (sum = I = 0; I <3; I ++)
For (j = 0; j <3; j ++)
{
T = cur-> sta [I] [J]-'0'-1;
Sum + = ABS (T/3-I) + ABS (T % 3-J );
}
Cur-> Dis = sum;
}
Void insert (node * cur, node * head)
{
Cur-> next = head-> next;
Head-> next = cur;
}
Int main (void)
{
Int I, j, Min, R, C;
Char table [362880] = {0}, temp [20], dir [4] [3] = {, 'D',-, 'U, 'R', 0,-1, 'L '};
Node * head, * cur, * t, * pre;
Head = (node *) malloc (sizeof (node ));
Head-> next = NULL;
Cur = (node *) malloc (sizeof (node ));
Cur-> ope = '\ B ';
Cur-> lev= 0;
For (I = 0; I <3; I ++)
For (j = 0; j <3; j ++)
{
Scanf ("% s", temp );
If ('x' = * temp)
{
Cur-> posr = I;
Cur-> POSC = J;
Cur-> sta [I] [J] = '9 ';
}
Else
Cur-> sta [I] [J] = * temp;
}
If (getpar (cur ))
{
Printf ("unsolvable ");
Return 0;
}
Brushdis (cur );
Insert (cur, head );
While (1)
{
For (min = (unsigned INT )(~ 0)> 1, pre = head, cur = head-> next; cur! = NULL; Pre = cur, cur = cur-> next)
If (cur-> DIS + cur-> EV <min)
{
Min = cur-> DIS + cur-> lev;
T = pre;
}
Cur = T-> next;
T-> next = cur-> next;
If (0 = cur-> dis)
{
End (cur, table );
Free (cur );
While (Head! = NULL)
{
Pre = head;
Head = head-> next;
Free (pre );
}
Return 0;
}
For (I = 0; I <4; I ++)
{
R = cur-> posr + dir [I] [0];
C = cur-> POSC + dir [I] [1];
If (r> = 0 & R <3 & C> = 0 & C <3)
{
T = (node *) malloc (sizeof (node ));
For (j = 0; j <9; j ++)
* (* T-> sta + J) = * (* cur-> sta + J );
T-> sta
[C] = '9 ';
T-> sta [cur-> posr] [cur-> POSC] = cur-> sta
[C];
If (Table [Hash (t)])
{
Free (t );
Continue;
}
T-> ope = dir [I] [2];
T-> posr = R;
T-> POSC = C;
T-> lev_= cur-> lev_+ 1;
Brushdis (t); // It can also be computed using cur-> dis
Insert (T, head );
}
}
Table [Hash (cur)] = cur-> ope;
Free (cur );
}
}