• HDU1043 Eight(BFS)


      Eight(South Central USA 1998)
    Time Limit:5000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

    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
     
    题目简单翻译:
    八数码
    给你一个八数码:(格式是一个九宫格,x代表空),问怎么操作能达到目标,即:
    1 2 3
    4 5 6
    7 8 x
    u代表空格向上交换,d代表空格向下交换,l代表空格向左交换,r代表空格向右交换。
    例如:
    给你一个八数码:
    1 2 3
    x 4 6
    7 5 8
    则把它变成目标需要三步:
    1 2 3   r   1 2 3   d   1 2 3  r   1 2 3
    x 4 6  --->  4 x 6  --->  4 5 6  --->  4 5 6
    7 5 8      7 5 8      7 x 8      7 8 x
    所以这个样例应该输出:
    rdr
    如果不能到达目标就输出“unsolvable”.
     
    解题思路:广度优先搜索(BFS)
    因为是多组数据,我们可以先求出所有情况,然后每次询问的时候直接输出结果就好了。
    求出所有结果,我们就可以根据结果,来逆向bfs,直到所有的情况都求到。
     
    代码:
      1 #include<cstdio>
      2 #include<string>
      3 #include<queue>
      4 #include<cstring>
      5 using namespace std;
      6 struct node
      7 {
      8     int t[3][3],x,y,Can;
      9     int Last_Can,dir;
     10 } St[370000];
     11 int fac[]= {1,1,2,6,24,120,720,5040,40320};
     12 //康托展开的数组
     13 //康托展开就是把一组数据按照字典序排列的那组数据的序号
     14 
     15 int vis[370000];
     16 queue<int> Q;
     17 char dr[]="rlud";
     18 int  dx[]= {0,0,1,-1};
     19 int  dy[]= {-1,1,0,0};
     20 //方向数组,与实际的方向相反,因为是逆向操作
     21 int Cantor(int *t)//对一组数据求康拓值
     22 {
     23     int rev=0;
     24     for(int i=0; i<9; i++)
     25     {
     26         int counted=0;
     27         for(int j=i+1; j<9; j++)
     28             if(t[i]>t[j]) counted++;
     29         rev+=counted*fac[8-i];
     30     }
     31     return rev;
     32 }
     33 bool check(int x,int y) //检查这个点是不是在矩形内
     34 {
     35     return x>=0&&x<3&&y>=0&&y<3;
     36 }
     37 void solve()//bfs求出所有的情况,并储存下来父节点
     38 {
     39     while(!Q.empty()) Q.pop();
     40     node st;
     41     st.x=st.y=2;
     42     int s[3][3]= {1,2,3,4,5,6,7,8,0};
     43     int t[9];
     44     for(int i=0; i<3; i++)
     45         for(int j=0; j<3; j++)
     46             t[i*3+j]=s[i][j];
     47     for(int i=0; i<3; i++)
     48         for(int j=0; j<3; j++)
     49             st.t[i][j]=s[i][j];
     50     int StCan=Cantor(t);
     51     st.Can=StCan;
     52     st.Last_Can=-1;
     53     st.dir=-1;
     54     memset(vis,0,sizeof vis);
     55     vis[StCan]=1;
     56     St[StCan]=st;
     57     Q.push(StCan);
     58     int Sum=0;
     59     while(!Q.empty())
     60     {
     61         Sum++;
     62         int TempCan=Q.front();
     63         Q.pop();
     64         for(int i=0; i<4; i++)
     65         {
     66             node e=St[TempCan];
     67             int curx=e.x+dx[i];
     68             int cury=e.y+dy[i];
     69             if(check(curx,cury))
     70             {
     71                 int c=e.t[curx][cury];
     72                 e.t[curx][cury]=e.t[e.x][e.y];
     73                 e.t[e.x][e.y]=c;
     74                 e.x=curx;
     75                 e.y=cury;
     76                 int t[9];
     77                 for(int i=0; i<3; i++)
     78                     for(int j=0; j<3; j++)
     79                         t[i*3+j]=e.t[i][j];
     80                 e.Can=Cantor(t);
     81                 e.Last_Can=TempCan;
     82                 e.dir=i;
     83                 if(!vis[e.Can])
     84                 {
     85                     vis[e.Can]=1;
     86                     St[e.Can]=e;
     87                     Q.push(e.Can);
     88                 }
     89             }
     90         }
     91     }
     92 }
     93 int main()
     94 {
     95     char c[10];
     96     int t[9],x=0;
     97     solve();
     98     while(scanf("%s",c)!=EOF)
     99     {
    100         if(c[0]=='x') c[0]='0';
    101         t[0]=c[0]-'0';
    102         for(int i=1;i<9;i++)
    103         {
    104             scanf("%s",c);
    105             if(c[0]=='x') c[0]='0';
    106             t[i]=c[0]-'0';
    107         }
    108         int AnsCan=Cantor(t);
    109         if(vis[AnsCan])
    110         {
    111             int p=AnsCan;
    112             while(St[p].Last_Can+1)
    113             {
    114                 printf("%c",dr[St[p].dir]);
    115                 p=St[p].Last_Can;
    116             }
    117             printf("
    ");
    118         }
    119         else
    120             printf("unsolvable
    ");
    121     }
    122     return 0;
    123 }
    Eight
     
  • 相关阅读:
    heat模板
    Leetcode812.Largest Triangle Area最大三角形面积
    Leetcode812.Largest Triangle Area最大三角形面积
    Leetcode811.Subdomain Visit Count子域名访问计数
    Leetcode811.Subdomain Visit Count子域名访问计数
    Leetcode806.Number of Lines To Write String写字符串需要的行数
    Leetcode806.Number of Lines To Write String写字符串需要的行数
    Leetcode819.Most Common Word最常见的单词
    Leetcode819.Most Common Word最常见的单词
    Leetcode783.Minimum Distance Between BST Nodes二叉搜索树结点最小距离
  • 原文地址:https://www.cnblogs.com/I-love-HLD/p/4624604.html
Copyright © 2020-2023  润新知