• ACWing845 八数码(BFS,全排列hash)


    原题
    思路:本题题意比较清楚,要找到最小的操作数,我们可以将每次九宫格表示的不同字符串看做一种不同的状态,从一种状态变化到另一种状态,则操作数 +1,问你从起始状态变化到目标状态的最小操作数,那么本题可以看做是求一个各边权值相同的最短路问题,所以用BFS即可。因为我们要记录每种状态是否走过,可将这种状态的字符串hash为一个数字,而如果直接字符串hash无法控制数值大小,v[N]数组(记录访问数组)可能开很大,如果使用康拓展开(全排列hash),那么就能保证最大hash值为10!,且不会冲突。

    全排列hash:一个字符串的hash值为从 0~i 位对 d[i] * (i!) 求和,其中 d[i] 表示第 i 位上逆序对的数量。使用这种方法不会浪费空间且绝不冲突,时间复杂度 O(n*n),n(字符串长度)最好不要超过12

    代码:

    //康拓展开全排列hash
    #include<bits/stdc++.h>
    using namespace std;
    const int N = 5e6+10;
    int v[N],p[10],dis[N];
    int dir[4][2]={-1,0,1,0,0,1,0,-1};
    int hashxx(string s)
    {
      int ans=0;
      for(int i=0;i<9;i++)
      {
          int d=0;
        for(int j=0;j<i;j++)
        {
          if(s[j]>s[i])
            d++;
        }
        ans+=d*p[i];
      }
      return ans;
    }
    int bfs(string start)
    {
       dis[hashxx(start)]=0;
       string ee="12345678x";
       queue<string>q;
       q.push(start);
       while(!q.empty())
       {
         string z=q.front();
         q.pop();
         if(z==ee)
            return dis[hashxx(z)];
         int t=z.find('x');
         int juli=dis[hashxx(z)];
         int x=t/3,y=t%3;
         for(int i=0;i<4;i++)
         {
           int a=x+dir[i][0];
           int b=y+dir[i][1];
           if(0<=a&&a<3&&0<=b&&b<3)
           {
              swap(z[a*3+b],z[t]);
              if(!v[hashxx(z)])
              {
                v[hashxx(z)]=1;
                dis[hashxx(z)]=juli+1;
                q.push(z);
              }
              swap(z[a*3+b],z[t]);
           }
         }
       }
       return -1;
    }
    int main()
    {
       p[0]=1;
       for(int i=1;i<10;i++)
       {
         p[i]=p[i-1]*i;//先预处理出阶乘数
       }
       string s,start;
       for(int i=1;i<=9;i++)
       {
         cin>>s;
         start+=s;
       }
       cout<<bfs(start);
    return 0;
    }
    
    
    戒骄戒躁,百炼成钢!
  • 相关阅读:
    Docker
    内存与缓存
    硬盘和内存的关系
    磁盘和硬盘、软盘
    mysql和redis的区别
    BZOJ 3110 k大数查询 (树套树)
    Codeforces 1303E Erase Subsequences (子序列匹配)
    Codeforces 1304E 1-Trees and Queries (树上距离+思维)(翻译向)
    BZOJ 2161 布娃娃(权值线段树)
    2019icpc徐州现场赛 H Yuuki and a problem (树状数组套主席树)
  • 原文地址:https://www.cnblogs.com/Pecoz/p/13732635.html
Copyright © 2020-2023  润新知