八数码第二境界——暴力反向BFS+康托展开判重

来源:互联网 发布:车牌照制作软件 编辑:程序博客网 时间:2024/06/06 00:30

(八数码的第一境界必须看了再看本文)

与上文有所区别,上文采用的是string存储状态,这里采用的是char[],可以增加性能。

上文采用的是map判重,这里采用的是康托展开看看是全排列的第几个来判重。


所以本文最大的问题是领悟康托展开。因为这里是1到x占据9个位置,所以就等于是求这9个位置的全排列了,而了解全排列的人会知道,康托展开是做全排列最好的方式。如果不太清楚用康托展开求全排列的同学,可以看http://blog.csdn.net/qq_36523667/article/details/78659214


结构体

  1. struct node  
  2. {  
  3.     char str[10];  
  4.     vector<int>res;  
  5.     int index,hashnum;  
  6. };  

数组通过康托展开求得是全排列的第几个,他这里转化成hash值仅仅是便于比较大小

                        int  fac[] = {1,1,2,6,24,120,720,5040,40320}; 

  1. int KT(char ss[])  
  2. {  
  3.     int i, j, t, sum;  
  4.     int s[10];  
  5.     for(i=0;i<9;i++)  
  6.     {  
  7.         if(ss[i]=='x')  
  8.             s[i]=0;  
  9.         else  
  10.             s[i]=ss[i]-'0';  
  11.     }  
  12.     sum = 0;  
  13.     for (i=0; i<9; i++)  
  14.     {  
  15.         t = 0;  
  16.         for (j=i+1; j<9; j++)  
  17.             if (s[j] < s[i])  
  18.                 t++;  
  19.         sum += t*fac[9-i-1];  
  20.     }  
  21.     return sum+1;  
  22. }  
不多解释了,不明白康托排序这个方法很难看懂的。


具体的BFS,和上文基本类似

  1. while(!q.empty())  
  2.     {  
  3.         g=q.front();q.pop();  
  4.         if(KT(g.str)==over)  
  5.         {  
  6.             res=g.res;  
  7.             return true;  
  8.         }  
  9.         h=g;  
  10.         if((h.index+1)%3!=0)  
  11.         {  
  12.             c=h.str[h.index];h.str[h.index]=h.str[h.index+1];h.str[h.index+1]=c;  
  13.             h.index++;  
  14.             h.res.push_back(4);  
  15.             int t=KT(h.str);  
  16.             if(!vis[t])  
  17.             {  
  18.                 vis[t]=true;  
  19.                 q.push(h);  
  20.             }  
  21.         }  
第一个if判断是否找到一样的

第二个if,是不为最后一列的情况,肯定可以右移

和右边的数交换

x在char中的索引加一位

4入vector,4代表右移操作

最后用康托找到是全排列的第几个,看看有没有访问过,没访问过就置为已访问状态,并且入队列。


全部代码

  1. #define N 512345  
  2.   
  3. char ss[10];  
  4. struct node  
  5. {  
  6.     char str[10];  
  7.     vector<int>res;  
  8.     int index,hashnum;  
  9. };  
  10. vector<int>res;  
  11. bool vis[N];  
  12. int  fac[] = {1,1,2,6,24,120,720,5040,40320};  
  13. int over;  
  14. int KT(char ss[])  
  15. {  
  16.     int i, j, t, sum;  
  17.     int s[10];  
  18.     for(i=0;i<9;i++)  
  19.     {  
  20.         if(ss[i]=='x')  
  21.             s[i]=0;  
  22.         else  
  23.             s[i]=ss[i]-'0';  
  24.     }  
  25.     sum = 0;  
  26.     for (i=0; i<9; i++)  
  27.     {  
  28.         t = 0;  
  29.         for (j=i+1; j<9; j++)  
  30.             if (s[j] < s[i])  
  31.                 t++;  
  32.         sum += t*fac[9-i-1];  
  33.     }  
  34.     return sum+1;  
  35. }  
  36. bool bfs(char ss[])  
  37. {  
  38.     char c;  
  39.     queue<node> q;  
  40.     while(!q.empty())q.pop();  
  41.     over = KT(ss);  
  42.     node g,h;  
  43.     for(int i=0;i<8;i++)  
  44.         g.str[i]=i+1+'0';  
  45.     g.str[8]='x';g.str[9]='\0';  
  46.     g.res.clear();g.index=8;  
  47.     q.push(g);  
  48.     while(!q.empty())  
  49.     {  
  50.         g=q.front();q.pop();  
  51.         if(KT(g.str)==over)  
  52.         {  
  53.             res=g.res;  
  54.             return true;  
  55.         }  
  56.         h=g;  
  57.         if((h.index+1)%3!=0)  
  58.         {  
  59.             c=h.str[h.index];h.str[h.index]=h.str[h.index+1];h.str[h.index+1]=c;  
  60.             h.index++;  
  61.             h.res.push_back(4);  
  62.             int t=KT(h.str);  
  63.             if(!vis[t])  
  64.             {  
  65.                 vis[t]=true;  
  66.                 q.push(h);  
  67.             }  
  68.         }  
  69.         h=g;  
  70.         if(h.index%3!=0)  
  71.         {  
  72.             c=h.str[h.index];h.str[h.index]=h.str[h.index-1];h.str[h.index-1]=c;  
  73.             h.index--;  
  74.             h.res.push_back(3);  
  75.             int t=KT(h.str);  
  76.             if(!vis[t])  
  77.             {  
  78.                 vis[t]=true;  
  79.                 q.push(h);  
  80.             }  
  81.         }  
  82.         h=g;  
  83.         if(h.index<6)  
  84.         {  
  85.             c=h.str[h.index];h.str[h.index]=h.str[h.index+3];h.str[h.index+3]=c;  
  86.             h.index+=3;  
  87.             h.res.push_back(2);  
  88.             int t=KT(h.str);  
  89.             if(!vis[t])  
  90.             {  
  91.                 vis[t]=true;  
  92.                 q.push(h);  
  93.             }  
  94.         }  
  95.         h=g;  
  96.         if(h.index>2)  
  97.         {  
  98.             c=h.str[h.index];h.str[h.index]=h.str[h.index-3];h.str[h.index-3]=c;  
  99.             h.index-=3;  
  100.             h.res.push_back(1);  
  101.             int t=KT(h.str);  
  102.             if(!vis[t])  
  103.             {  
  104.                 vis[t]=true;  
  105.                 q.push(h);  
  106.             }  
  107.         }  
  108.     }  
  109.     return false;  
  110. }  
  111. int main()  
  112. {  
  113.     int i,j,k,kk,t,x,y,z;  
  114.     while(scanf("%s",ss)!=EOF)  
  115.     {  
  116.         memset(vis,false,sizeof(vis));  
  117.         for(i=1;i<9;i++)  
  118.             scanf("%s",ss+i);  
  119.         if(bfs(ss))  
  120.             for(i=res.size()-1;i>=0;i--)  
  121.             {  
  122.                 if(res[i]==1)printf("d");  
  123.                 if(res[i]==2)printf("u");  
  124.                 if(res[i]==3)printf("r");  
  125.                 if(res[i]==4)printf("l");  
  126.             }  
  127.         else  
  128.             printf("unsolvable");  
  129.         printf("\n");  
  130.     }  
  131.     return 0;  
  132. }  


阅读全文
0 0