hdu 1043 eight (搜索 + 康托展开)

来源:互联网 发布:被一个人爱的感觉知乎 编辑:程序博客网 时间:2024/05/17 22:28

Eight

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


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 1213 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 1213 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
 
#include<iostream>#include<algorithm>#include<cstdlib>#include<cctype>#include<cstdio>#include<string>#include<cstring>#include<vector>#include<set>#include<map>#include<queue>#include<cmath>#define pi acos(-1.0)#define inf 1<<29#define INF 0x3f3f3f3f#define zero 1e-8using namespace std;const int N = 500000;int as[] = {40320,5040,720,120,24,6,2,1,0};bool flag[N];string ttt[4]={"l","r","u","d"};string arr[N];int li[]={0,0,1,-1};int lj[]={1,-1,0,0};struct lo{    int x,y;    int step;    int tip;//康拓展开值    lo()=default;    lo(int x,int y,int step,int tip):x(x),y(y),step(step),tip(tip){}    lo(const lo& a):x(a.x),y(a.y),step(a.step),tip(a.tip){}    bool operator < (const lo& b)const{        return step>b.step;    }}every[1000000];int head,tail;int findnum(char* str){    int tot=0;    for (int i=8;i>=0;--i){        int cnt=0;        for (int j=i-1;j>=0;--j)            if (str[j]<str[i]) cnt++;        tot+=(str[i]-'0'-cnt-1)*as[i];    }    return tot;}int findnum(char (*str1)[3]){    int tot=0;    char strr[10];    for (int i=0;i<3;++i)        for (int j=0;j<3;++j)            strr[tot++]=str1[i][j];    strr[9]='\0';    return findnum(strr);}void findstr(char* str,int tip){    int r,p;    bool ff[17]={};    int j;    for (int i=0;i<8;++i){        r=tip%as[i];        p=tip/as[i];        int cnt=0;        for (j=1;j<=9;++j){            if (!ff[j]) cnt++;            if (cnt==p+1) break;        }        ff[j]=true;        str[i]=j+'0';        tip=r;        }        for (j=1;j<=9;++j){            if (!ff[j]) {                    str[8]=j+'0';            }        }}void YCL(){    int t=1;    while(1){    while (head!=tail){        if (!flag[every[head].tip]) break;        head++;    }    if (head==tail) {         return ;    }    lo tem(every[head]);    head++;    char str1[10];//图    findstr(str1,tem.tip);    str1[9]='\0';    flag[tem.tip]=true;    char str2[3][3];    for (int i=0;i<3;++i)        for (int j=0;j<3;++j)            str2[i][j]=*(str1+i*3+j);    int k=findnum(str2);    for (int i=0;i<4;++i){        if (tem.x+li[i]<0||tem.x+li[i]>=3            ||tem.y+lj[i]<0||tem.y+lj[i]>=3)                continue;//不能移动        int a=str2[tem.x][tem.y],b=str2[tem.x+li[i]][tem.y+lj[i]];        str2[tem.x][tem.y]=b;        str2[tem.x+li[i]][tem.y+lj[i]]=a;        int k=findnum(str2);        str2[tem.x+li[i]][tem.y+lj[i]]=str2[tem.x][tem.y];        str2[tem.x][tem.y]='9';        if (flag[k]) continue;//看图是不是已经存在        every[tail].x=tem.x+li[i];        every[tail].y=tem.y+lj[i];        every[tail].step=tem.step+1;        every[tail++].tip=k;        arr[k]=arr[tem.tip]+ttt[i];    }   }}int main(){    head=tail=0;    lo tem(2,2,0,0);    every[tail].x=2;    every[tail].y=2;    every[tail].step=0;    every[tail++].tip=0;    YCL();    string str;    while (getline(cin,str)){        char str1[10],m=0;        for(int i=0;str[i];++i){            if  (str[i]>='0'&&str[i]<='8'){                 str1[m++]=str[i];            }            if (str[i]=='x'){                str1[m++]='9';            }        }        int fin=findnum(str1);        string b;        if (flag[fin]){            if (fin){            for (auto it=arr[fin].end()-1;;--it){                cout<<(*it);                if (it==arr[fin].begin()) {                    break;                }            }           }        }        else {           printf("unsolvable");        }        puts("");    }  return 0;}


 
0 0