HDU 1043 Eight(BFS+康拓铺展)

HDU 1043 Eight(BFS+康拓展开)
Problem 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, 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 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. Do not print a blank line between cases.
 

Sample Input
2 3 4 1 5 x 7 6 8
 

Sample Output
ullddrurdllurdruldr
由于状态多,正向搜素超时,所以我们从目标状态开始反向搜索,预处理到达每个
状态的走法;这里唯一不好表示的就是状态和走法,走法我们选择string类,而状态
我们则用康拓展开,对于给出n个互不相同的字符的状态,康拓展开很实用。自此解决了。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<string>
#include<iostream>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#include<bitset>
using namespace std;
#define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define CLEAR( a , x ) memset ( a , x , sizeof a )
typedef long long LL;
const int maxn = 400000;
const int mod = 1000000007;
int fac[]={1,1,2,6,24,120,720,5040,40320,362880};
int dr[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
struct node
{
    int s[9];
    int pos;
    int val;
    string path;
};
int hash[maxn],num[9];
string path[maxn];
char index[5]="durl";
int Hash(int a[])
{
	int sum=0;
    REPF(i,1,8)
    {
    	int num=0;
    	for(int j=0;j<i;j++)
    		if(a[j]>a[i])  num++;
    	sum+=num*fac[i];
    }
    return sum;
}
void BFS()
{
   CLEAR(hash,0);
   node st,ed;
   REP(i,8)  st.s[i]=i+1;
   st.s[8]=9;
   st.pos=8;st.val=Hash(st.s);
   st.path="";
   queue<node>q;
   path[st.val]="";
   q.push(st);
   while(!q.empty())
   {
       st=q.front();
       q.pop();
       int x=st.pos/3;
       int y=st.pos%3;
       REP(i,4)
       {
           int xx=x+dr[i][0];
           int yy=y+dr[i][1];
           if(xx>=0&&xx<=2&yy>=0&&yy<=2)
           {
               ed=st;
               ed.pos=xx*3+yy;
               ed.s[st.pos]=ed.s[ed.pos];
               ed.s[ed.pos]=9;
               ed.val=Hash(ed.s);
               if(!hash[ed.val])
               {
                  hash[ed.val]=1;
                  ed.path=index[i]+ed.path;
                  q.push(ed);
                  path[ed.val]=ed.path;
               }
           }
       }
   }
}
int main()
{
    char str[110];
    BFS();
    while(gets(str))
    {
        int len=strlen(str);
        int l=0;
        REP(i,len)
        {
            if(str[i]>='0'&&str[i]<='9')
                num[l++]=str[i]-'0';
            else if(str[i]=='x')   num[l++]=9;
        }
        if(hash[Hash(num)]) cout<<path[Hash(num)]<<endl;
        else   cout<<"unsolvable"<<endl;
    }
    return 0;
}