zoukankan      html  css  js  c++  java
  • POJ 1077 8数码问题(BFS)

    Eight

    Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 131072/65536K (Java/Other)
    Total Submission(s) :    Accepted Submission(s) : 
    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 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
    PKU
     

    整个程序由以下部分组成:结点,cantor展开(当HASH函数用的),移动函数,BFS,输出函数

    由于有调试的部分在里面而且移动函数也不是特别简洁所以显得特别长,BFS效率低下也只有在弱数据的POJ 1077可以过

      1 #include <iostream>
      2 #include <cstring>
      3 #include <algorithm>
      4 #include <queue>
      5 #include <stack>
      6 #include <stdio.h>
      7 
      8 #define MAX 500000
      9 
     10 char str[400000];
     11     int tot=0;
     12 
     13 using namespace std;
     14 
     15 struct Note
     16 {
     17     char s[9];//数码串
     18     int num;//第多少号
     19     int fa;//父结点是多少号
     20     char dir;//从父结点MOVE方向
     21 }note[MAX];
     22 
     23 queue<Note> q;
     24 
     25 int vis[MAX];
     26 
     27 int cantor(char* s)
     28 {
     29     int len=9;
     30 
     31     int sum=0;
     32     for(int i=0;i<len;i++)
     33     {
     34         int a=0;
     35         int b=1;
     36         for(int j=i+1;j<len;j++)
     37             if(s[j]<s[i])
     38             {
     39                 a=a+1;
     40             }
     41         //sum+=a*(8-i)!
     42         for(int k=1;k<len-i;k++)
     43         {
     44             b*=k;
     45         }
     46 
     47         sum+=a*b;
     48     }
     49 
     50     return sum;
     51 
     52 }
     53 
     54 int move4(char *s,int n)
     55 {
     56     //会对S进行改变
     57     //返回1表示进行了移动,返回0表示没有移动
     58     int pos;
     59     int len=9;
     60     if(n==1)//move up
     61     {
     62         for(int i=0;i<len;i++)
     63         {
     64             if(s[i]=='9')
     65             {
     66                 pos=i;
     67                 break;
     68             }
     69         }
     70         if(pos-3>=0)
     71         {
     72             s[pos]=s[pos-3]^s[pos];
     73             s[pos-3]=s[pos]^s[pos-3];
     74             s[pos]=s[pos]^s[pos-3];
     75 
     76             return 1;
     77         }
     78         else
     79             return 0;
     80     }
     81     if(n==2)//move down
     82     {
     83         for(int i=0;i<len;i++)
     84         {
     85             if(s[i]=='9')
     86             {
     87                 pos=i;
     88                 break;
     89             }
     90         }
     91         if(pos+3<9)
     92         {
     93             s[pos]=s[pos+3]^s[pos];
     94             s[pos+3]=s[pos]^s[pos+3];
     95             s[pos]=s[pos]^s[pos+3];
     96 
     97             return 1;
     98         }
     99         else
    100             return 0;
    101     }
    102     if(n==3)//move left
    103     {
    104         for(int i=0;i<len;i++)
    105         {
    106             if(s[i]=='9')
    107             {
    108                 pos=i;
    109                 break;
    110             }
    111         }
    112         if(pos-1>=0&&(pos/3==(pos-1)/3))
    113         {
    114             s[pos]=s[pos-1]^s[pos];
    115             s[pos-1]=s[pos]^s[pos-1];
    116             s[pos]=s[pos]^s[pos-1];
    117 
    118             return 1;
    119         }
    120         else
    121             return 0;
    122     }
    123     if(n==4)//move right
    124     {
    125         for(int i=0;i<len;i++)
    126         {
    127             if(s[i]=='9')
    128             {
    129                 pos=i;
    130                 break;
    131             }
    132         }
    133         if(pos+1<9&&(pos/3==(pos+1)/3))
    134         {
    135             s[pos]=s[pos+1]^s[pos];
    136             s[pos+1]=s[pos]^s[pos+1];
    137             s[pos]=s[pos]^s[pos+1];
    138 
    139             return 1;
    140         }
    141         else
    142             return 0;
    143     }
    144 
    145     return 0;
    146 }
    147 
    148 int bfs()
    149 {
    150     while(!q.empty())
    151     {
    152         int ok=1;
    153         Note t=q.front();
    154         Note t2=q.front();
    155         q.pop();
    156         for(int i=0;i<8;i++)
    157         {
    158             if(t.s[i]-48==i+1&&t.s[8]=='9')
    159                    ;
    160             else
    161                 {
    162                     ok=0;
    163                 }
    164         }
    165  //       cout<<"判断是否可以结束:  "<<ok<<endl;
    166 
    167         if(ok)
    168         {
    169             return t.fa;
    170         }
    171  //           cout<<"还要继续搜索。。。"<<endl;
    172             t2=t;//cout<<"up up up\n";
    173             if(move4(t2.s,1))
    174             {
    175    //             cout<<"向上走。。。"<<endl;
    176 
    177                 int k=cantor(t2.s);
    178                 if(vis[k]==0)
    179                 {
    180  //                   cout<<"行。。。"<<endl;
    181                     t2.dir='u';
    182                     t2.fa=t.num;
    183 /*
    184                     cout<<"k: "<<k<<" fa:"<<t2.fa<<endl;
    185                     for(int i=0;i<9;i++)
    186                     {
    187                         cout<<t2.s[i]<<" ";
    188                         if((i+1)%3==0) cout<<endl;
    189                     }
    190                     cout<<t2.dir<<endl;
    191 
    192 */
    193                     t2.num=k;
    194                     note[k]=t2;
    195                     q.push(t2);
    196                     vis[k]=1;
    197                 }
    198   //              else cout<<"不行。。。"<<endl;
    199             }
    200             t2=t; // cout<<"down down down\n";
    201             if(move4(t2.s,2))
    202             {
    203   //              cout<<"向下走。。。"<<endl;
    204 
    205                 int k=cantor(t2.s);
    206                 if(vis[k]!=1)
    207                 {
    208                     t2.dir='d';
    209                     t2.fa=t.num;
    210   //                   cout<<"行。。。"<<endl;
    211 /*
    212                     cout<<"k: "<<k<<" fa:"<<t2.fa<<endl;
    213                     for(int i=0;i<9;i++)
    214                     {
    215                         cout<<t2.s[i]<<" ";
    216                         if((i+1)%3==0) cout<<endl;
    217                     }
    218                     cout<<t2.dir<<endl;
    219 */
    220                     t2.num=k;
    221                     note[k]=t2;
    222                     q.push(t2);
    223                     vis[k]=1;
    224                 }
    225   //              else cout<<"不行。。。"<<endl;
    226             }
    227             t2=t; // cout<<"left left left\n";
    228             if(move4(t2.s,3))
    229             {
    230   //              cout<<"向左走。。。"<<endl;
    231 
    232                 int k=cantor(t2.s);
    233                 if(vis[k]!=1)
    234                 {
    235                     t2.dir='l';
    236                     t2.fa=t.num;
    237     //                 cout<<"行。。。"<<endl;
    238 /*
    239                     cout<<"k: "<<k<<" fa:"<<t2.fa<<endl;
    240                     for(int i=0;i<9;i++)
    241                     {
    242                         cout<<t2.s[i]<<" ";
    243                         if((i+1)%3==0) cout<<endl;
    244                     }
    245                     cout<<t2.dir<<endl;
    246 
    247   */                  t2.num=k;
    248                     note[k]=t2;
    249                     q.push(t2);
    250                     vis[k]=1;
    251                 }
    252    //            else cout<<"不行。。。"<<endl;
    253             }
    254             t2=t; //cout<<"right right right\n";
    255             if(move4(t2.s,4))
    256             {
    257    //             cout<<"向右走。。。"<<endl;
    258 
    259                 int k=cantor(t2.s);
    260                 if(vis[k]!=1)
    261                 {
    262                     t2.dir='r';
    263                     t2.fa=t.num;
    264                     // cout<<"行。。。"<<endl;
    265 
    266 /*
    267                     cout<<"k: "<<k<<" fa:"<<t2.fa<<endl;
    268                     for(int i=0;i<9;i++)
    269                     {
    270                         cout<<t2.s[i]<<" ";
    271                         if((i+1)%3==0) cout<<endl;
    272                     }
    273                     cout<<t2.dir<<endl;
    274 */
    275                     t2.num=k;
    276                     note[k]=t2;
    277                     q.push(t2);
    278                     vis[k]=1;
    279                 }
    280   //              else cout<<"不行。。。"<<endl;
    281             }
    282 
    283     }
    284 
    285     return -999;
    286 }
    287 
    288 
    289 void print (int p)
    290 {
    291     stack < char > stck;
    292     while ( note[p].dir!='Q' )
    293     {
    294         stck.push(note[p].dir);
    295         p = note[p].fa;
    296     }
    297     while ( !stck.empty() )
    298     {
    299         putchar ( stck.top() );
    300         stck.pop();
    301     }
    302     putchar ('\n');
    303 }
    304 
    305 
    306 int main()
    307 {
    308     memset(vis,0,sizeof(vis));
    309     Note t;
    310     for(int i=0;i<9;i++)
    311     {
    312         char c;
    313         cin>>c;
    314         if(c=='x')
    315         {
    316             t.s[i]='9';
    317         }
    318         else t.s[i]=c;
    319     }
    320 
    321     int k=cantor(t.s);
    322     t.num=k;
    323     t.fa=-998;
    324     t.dir='Q';
    325     note[k]=t;
    326 
    327     q.push(t);
    328 
    329     int B=bfs();
    330     note[k].dir='Q';
    331     note[k].fa=-998;
    332     ///xxxxxx
    333     if(B==-999)  cout<<"unsolvable"<<endl;
    334 
    335   //  cout<<"B:  "<<B<<endl;
    336 
    337     print(0);
    338 
    339     return 0;
    340 }
  • 相关阅读:
    面向对象定义
    xml与面上对象初识
    模块configparser/subprocess/表格处理模块
    python模块
    python-判断语句
    python了解
    Qt Qwdget 汽车仪表知识点拆解7 图像绘制,旋转
    Qt Qwdget 汽车仪表知识点拆解6 自定义控件
    Qt Qwdget 汽车仪表知识点拆解5 标题栏图标闪烁
    Qt Qwdget 汽车仪表知识点拆解4 另类进度条实现
  • 原文地址:https://www.cnblogs.com/CKboss/p/3017894.html
Copyright © 2011-2022 走看看