poj 1077 Eight 八数码

poj 1077 Eight 八数码
http://acm.pku.edu.cn/JudgeOnline/problem?id=1077

Description

The 15-puzzle has been around for over 100 years; even if you don't know it by 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 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 as:
 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 many 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 should 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


八数码 经典的BFS啊, 我就直接用的单向的BFS,也过了,双向的应该会快很多。
判重的hash函数看的discuss里的,用逆序数,9!种情况,一一对应,不会有重复的。


 

Source Code
Problem: 1077
User: lovecanon
Memory: 9572K
Time: 125MS
Language: GCC
Result: Accepted
  • Source Code
  • 
        
        
        
        
        
    #include < stdio.h >
    #include
    < string .h >
    #include
    < stdlib.h >
    struct  node
    {
        
    int  state[ 3 ][ 3 ];
        
    int  pre;
        
    int  dir;
    }queue[
    362881 ];
    int  hash[ 362881 ];
    int  step[ 362881 ];
    int  a[ 3 ][ 3 ];

    int  fac( int  i)
    {
        
    switch (i)
        {
            
    case   0 return   1 ;
            
    case   1 return   1 ;
            
    case   2 return   2 ;
            
    case   3 return   6 ;
            
    case   4 return   24 ;
            
    case   5 return   120 ;
            
    case   6 return   720 ;
            
    case   7 return   5040 ;
            
    case   8 return   40320 ;
        }
        
    return   0 ;
    }

    int  HASH()
    {
        
    int  i,j,k = 0 ,b[ 9 ],ret = 0 ,num = 0 ;
        
    for (i = 0 ;i < 3 ;i ++ )
            
    for (j = 0 ;j < 3 ;j ++ )
                b[k
    ++ ] = a[i][j];
        
    for (i = 0 ;i < 9 ;i ++ )
        {
            num
    = 0 ;
            
    for (j = 0 ;j < i;j ++ )
                
    if (b[j] > b[i])  num ++ ;
            ret
    += fac(i) * num;
        }
        
    return  ret;
    }

    void  output( int  len)
    {
        
    int  i;
        
    for (i = len;i >= 0 ;i --
        {
            
    if (step[i] == 1 ) printf( " l " );
            
    if (step[i] == 2 ) printf( " r " );
            
    if (step[i] == 3 ) printf( " u " );
            
    if (step[i] == 4 ) printf( " d " );
        }
        printf(
    " \n " );
    }

    int  main()
    {
        
    char  s[ 10 ];
        
    int  i,j,rear = 0 ,front = 0 ,tag = 0 ;

        rear
    ++ ;
        
    for (i = 0 ;i < 3 ;i ++ )
            
    for (j = 0 ;j < 3 ;j ++ )
            {
                scanf(
    " %s " ,s);
                
    if (s[ 0 ] == ' x ' )  s[ 0 ] = ' 9 ' ;
                queue[rear].state[i][j]
    = s[ 0 ] - ' 0 ' ;
            }
        queue[rear].pre
    = 0 ;queue[rear].dir = 0 ;
        
    for (i = 0 ;i < 3 ;i ++ )
            
    for (j = 0 ;j < 3 ;j ++ )
                a[i][j]
    = queue[rear].state[i][j];

        hash[HASH()]
    = 1 ;
        
    while (front < rear)
        {
            
    int  e,f,tmp,cntdir,len;
            front
    ++ ;
            
    for (i = 0 ;i < 3 ;i ++ )
                
    for (j = 0 ;j < 3 ;j ++ )
                {
                    a[i][j]
    = queue[front].state[i][j];
                    
    if (a[i][j] == 9 ) {e = i;f = j;}
                }
            
    if (f - 1 >= 0 )
            {
                cntdir
    = 1 ;
                tmp
    = a[e][f];
                a[e][f]
    = a[e][f - 1 ];
                a[e][f
    - 1 ] = tmp;
                tmp
    = HASH();
                
    if (tmp == 0
                {
                    
    int  t = front;
                    len
    = 0 ;
                    step[len
    ++ ] = cntdir;
                    
    while (queue[t].pre)  
                    {
                        step[len
    ++ ] = queue[t].dir;
                        t
    = queue[t].pre;
                    }
                    output(len);
                    
    return   0 ;
                }
                
    if ( ! hash[tmp]) 
                {
                    rear
    ++ ;
                    
    for (i = 0 ;i < 3 ;i ++ )
                        
    for (j = 0 ;j < 3 ;j ++ )
                            queue[rear].state[i][j]
    = a[i][j];
                    queue[rear].dir
    = cntdir;queue[rear].pre = front;
                    hash[tmp]
    = 1 ;

                }
                tmp
    = a[e][f];
                a[e][f]
    = a[e][f - 1 ];
                a[e][f
    - 1 ] = tmp;
            }
            
    if (f + 1 < 3 )
            {
                cntdir
    = 2 ;
                tmp
    = a[e][f];
                a[e][f]
    = a[e][f + 1 ];
                a[e][f
    + 1 ] = tmp;
                tmp
    = HASH();
                
    if (tmp == 0
                {
                    
    int  t = front;
                    len
    = 0 ;
                    step[len
    ++ ] = cntdir;
                    
    while (queue[t].pre)  
                    {
                        step[len
    ++ ] = queue[t].dir;
                        t
    = queue[t].pre;
                    }
                    output(len);
                    
    return   0 ;
                }
                
    if ( ! hash[tmp]) 
                {
                    rear
    ++ ;
                    
    for (i = 0 ;i < 3 ;i ++ )
                        
    for (j = 0 ;j < 3 ;j ++ )
                            queue[rear].state[i][j]
    = a[i][j];
                    queue[rear].dir
    = cntdir;queue[rear].pre = front;
                    hash[tmp]
    = 1 ;
                }
                tmp
    = a[e][f];
                a[e][f]
    = a[e][f + 1 ];
                a[e][f
    + 1 ] = tmp;
            }
            
    if (e - 1 >= 0 )
            {
                cntdir
    = 3 ;
                tmp
    = a[e][f];
                a[e][f]
    = a[e - 1 ][f];
                a[e
    - 1 ][f] = tmp;
                tmp
    = HASH();
                
    if (tmp == 0
                {
                    
    int  t = front;
                    len
    = 0 ;
                    step[len
    ++ ] = cntdir;
                    
    while (queue[t].pre)  
                    {
                        step[len
    ++ ] = queue[t].dir;
                        t
    = queue[t].pre;
                    }
                    output(len);
                    
    return   0 ;
                }
                
    if ( ! hash[tmp]) 
                {
                    rear
    ++ ;
                    
    for (i = 0 ;i < 3 ;i ++ )
                        
    for (j = 0 ;j < 3 ;j ++ )
                            queue[rear].state[i][j]
    = a[i][j];
                    queue[rear].dir
    = cntdir;queue[rear].pre = front;
                    hash[tmp]
    = 1 ;

                }
                tmp
    = a[e][f];
                a[e][f]
    = a[e - 1 ][f];
                a[e
    - 1 ][f] = tmp;
            }
            
    if (e + 1 < 3 )
            {
                cntdir
    = 4 ;
                tmp
    = a[e + 1 ][f];
                a[e
    + 1 ][f] = a[e][f];
                a[e][f]
    = tmp;
                tmp
    = HASH();
                
    if (tmp == 0
                {
                    
    int  t = front;
                    len
    = 0 ;
                    step[len
    ++ ] = cntdir;
                    
    while (queue[t].pre)  
                    {
                        step[len
    ++ ] = queue[t].dir;
                        t
    = queue[t].pre;
                    }
                    output(len);
                    
    return   0 ;
                }
                
    if ( ! hash[tmp]) 
                {
                    rear
    ++ ;
                    
    for (i = 0 ;i < 3 ;i ++ )
                        
    for (j = 0 ;j < 3 ;j ++ )
                            queue[rear].state[i][j]
    = a[i][j];
                    queue[rear].dir
    = cntdir;queue[rear].pre = front;
                    hash[tmp]
    = 1 ;

                }
                tmp
    = a[e + 1 ][f];
                a[e
    + 1 ][f] = a[e][f];
                a[e][f]
    = tmp;
            }
        }
        printf(
    " unsolvable\n " );
        
    return   0 ;
    }

你可能感兴趣的:(poj 1077 Eight 八数码)