HDU 3567 Eight II BFS预处理

Posted shuguangzw

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 3567 Eight II BFS预处理相关的知识,希望对你有一定的参考价值。

题意:就是八数码问题,给你开始的串和结束的串,问你从开始到结束的最短且最小的变换序列是什么

分析:我们可以预处理打表,这里的这个题可以和HDU1430魔板那个题采取一样的做法

预处理打表,因为八数码问题实际上是每个小块位置的变化,上面的数字只是用来标记位置的,

所以通过映射将初末序列进行置换就好了,然后因为每次的x字符的置换位置不一样

所以需要以123456789这个初始串打9遍表就好了733ms

技术分享
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
#include <string>
#include <cmath>
#include <queue>
using namespace std;
const int N=5005;
int fac[]= {1,1,2,6,24,120,720,5040,40320,362880};
int aim;
int cantor(char s[])
{
    int ans=0;
    for(int i=1,j=8; i<=9; ++i,--j)
    {
        int tmp=0;
        for(int k=i+1; k<=9; ++k)
            if(s[i]>s[k])++tmp;
        ans+=(tmp*fac[j]);
    }
    return ans;
}
struct Node
{
    char s[10];
    int hs;
};
struct asd
{
   bool vis;
   char c;
   int pre;
}o[10][362880];
queue<Node>q;
void bfs(int pos)
{
    Node a;
    for(int i=1; i<=9; ++i)
        a.s[i]=0+i;
    aim=a.hs=cantor(a.s);
    o[pos][a.hs].vis=1;
    q.push(a);
    while(!q.empty())
    {
        a=q.front();
        q.pop();
        int now=a.hs;
        int x;
        for(int i=1; i<=9; ++i)
            if(a.s[i]==0+pos)x=i;
        if(x+3<10)
        {
            bool flag=0;
            swap(a.s[x],a.s[x+3]);
            a.hs=cantor(a.s);
            if(o[pos][a.hs].vis)
                flag=1;
            if(!flag)
            {
                o[pos][a.hs].vis=1;
                o[pos][a.hs].c=d;
                o[pos][a.hs].pre=now;
                q.push(a);
            }
            swap(a.s[x],a.s[x+3]);
        }
        if(x%3!=1)
        {
            bool flag=0;
            swap(a.s[x],a.s[x-1]);
            a.hs=cantor(a.s);
            if(o[pos][a.hs].vis)
                flag=1;
            if(!flag)
            {
                o[pos][a.hs].vis=1;
                o[pos][a.hs].c=l;
                o[pos][a.hs].pre=now;
                q.push(a);
            }
            swap(a.s[x],a.s[x-1]);
        }
        if(x%3)
        {
            bool flag=0;
            swap(a.s[x],a.s[x+1]);
            a.hs=cantor(a.s);
           if(o[pos][a.hs].vis)
                flag=1;
            if(!flag)
            {
                o[pos][a.hs].vis=1;
                o[pos][a.hs].c=r;
                o[pos][a.hs].pre=now;
                q.push(a);
            }
            swap(a.s[x],a.s[x+1]);
        }
        if(x-3>0)
        {
            bool flag=0;
            swap(a.s[x],a.s[x-3]);
            a.hs=cantor(a.s);
           if(o[pos][a.hs].vis)
                flag=1;
            if(!flag)
            {
                o[pos][a.hs].vis=1;
                o[pos][a.hs].c=u;
                o[pos][a.hs].pre=now;
                q.push(a);
            }
            swap(a.s[x],a.s[x-3]);
        }
    }
}
char s[15],t[15];
string res;
void getres(int u,int pos)
{
    while(u!=aim)
    {
       res=res+o[pos][u].c;
       u=o[pos][u].pre;
    }
}
char mat[13];
int main()
{
    for(int i=0;i<326880;++i)
     for(int j=1;j<=9;++j)
      o[j][i].vis=0;
    for(int i=1;i<=9;++i)
       bfs(i);
    int T,cas=0;
    scanf("%d",&T);
    while(T--)
    {
         scanf("%s%s",s+1,t+1);
         int flag;
         for(int i=1;i<=9;++i)
         {
             if(s[i]==X)s[i]=9,flag=i;
             if(t[i]==X)t[i]=9;
             mat[s[i]-0]=i+0;
         }
         for(int i=1;i<=9;++i)
            t[i]=mat[t[i]-0];
        int ans=cantor(t);
        res.clear();
        getres(ans,flag);
        printf("Case %d: %d\n",++cas,res.size());
        reverse(res.begin(),res.end());
        cout<<res<<endl;
    }
    return 0;
}
View Code

 

以上是关于HDU 3567 Eight II BFS预处理的主要内容,如果未能解决你的问题,请参考以下文章

HDU - 3567 Eight II IDA*

HDU 3567 Eight II(八数码 II)

HDU 1043 Eight BFS

HDOJ3567预处理bfs+映射+康拓展开hash

hdu 1043 Eight (八数码问题)BFS+康拓展开

HDU 1043 Eight(哈希 + BFS)